为何派生类B1公开基类A1保护构造函数后无法编译?
为什么B1编译失败,B2和D却正常?
核心是三种写法的访问权限规则完全不同
1. B1的问题根源
B1中使用using A1::A1;引入基类构造函数,这属于继承构造函数的声明,但它的权限逻辑和普通成员函数的using声明不一样:
- 当你在
main中尝试B1 b1(1);时,本质是通过B1的继承构造函数间接调用基类A1的protected构造函数。根据C++访问规则,外部代码(比如main)没有权限访问类的protected成员,哪怕是通过派生类的继承构造函数中转也不行。这种using声明只是把基类构造函数“暴露”在派生类的public区域,但权限检查依然追溯到基类的原始权限,再加上B1是private继承A1,外部连访问A1protected成员的合法路径都没有,因此编译报错。
2. B2能编译的原因
B2是自定义构造函数B2(int i) : A2(i) {},这是在派生类的成员函数(构造函数)内部调用基类的protected构造函数:
- 派生类的成员函数天生具备访问基类protected成员的权限,不管继承方式是private还是其他,只要是派生类内部的代码,就可以合法调用基类的protected构造函数完成初始化,所以编译完全正常。
3. D可以正常运行的逻辑
D中using C::f;是引入基类的普通成员函数,这种using声明的规则和继承构造函数不同:
- 它可以直接改变成员函数在派生类中的访问权限。基类
C的protected函数f,被D以public方式引入后,就成为了D的public成员函数。main中调用d.f(1),本质是调用D自身的public成员函数,完全符合访问规则,自然没问题。
总结一下:继承构造函数的using声明无法突破基类构造函数的原始权限限制,而普通成员函数的using声明可以调整派生类中的访问权限,自定义构造函数则是利用了派生类内部的访问特权。
内容的提问来源于stack exchange,提问作者Baruch
相关产品推荐
相关产品推荐

