继承基类构造函数与运算符时,派生类中继承成员的访问限定符规则咨询
继承基类构造函数与运算符时,派生类中继承成员的访问限定符规则咨询
先看你给出的测试代码和现象:
#include <cstdio> class base { public: base(int i) { printf("Public base class ctor called!"); } private: base(bool b) { printf("Private base class ctor called!"); } }; class derived final : public base { private: using base::base; }; int main() { derived d(2); // issues "is private within this context" // derived e(true); }
输出:
Public base class ctor called!
你的困惑是:明明把基类构造函数用private的using声明继承到派生类,却依然能在外部调用derived d(2);,这到底是怎么回事?
嘿,我来帮你搞清楚这个问题——你遇到的是C++里继承构造函数的一个容易混淆的特殊规则,和普通成员的继承规则不一样哦!
下面给你梳理具体规则:
一、继承构造函数的访问规则(重点!)
当你通过using base::base;继承基类构造函数时,外部调用派生类的继承构造函数时,访问权限的检查逻辑是看基类中对应构造函数的访问权限,再结合派生类对基类的继承方式,而派生类里using声明所在的访问限定符(比如你这里的private)并不影响外部访问——它只控制派生类内部成员是否能使用这个继承的构造函数。
拿你的代码举例:
- 基类的
base(int)是public,派生类是public继承base,所以这个构造函数在派生类外部是可见且可访问的,哪怕你把using base::base;放在private段,外部调用derived d(2);依然合法。 - 基类的
base(bool)是private,不管你怎么继承,外部都无法访问这个构造,所以derived e(true);会报“is private within this context”的错误,这和你的测试结果一致。
如果在派生类内部的成员函数里尝试调用这个继承的构造(比如derived(true);),这时候才会因为using声明是private而触发访问错误。
二、普通成员函数/运算符的继承规则(和构造函数不同)
对于基类的普通成员函数或者运算符(比如using base::operator+;),通过using声明引入派生类时,其在派生类中的访问权限由**using声明所在的访问限定符**决定,会覆盖基类的访问权限:
- 比如基类有一个public的
void func(),派生类里写private: using base::func;,那么派生类外部无法调用func(),但派生类内部可以正常使用。
总结一下
- 继承构造函数:外部访问看基类构造的访问权限 + 派生类继承方式,
using的访问限定只影响派生类内部使用。 - 普通成员/运算符:访问权限由
using声明所在的访问限定符决定,覆盖基类的权限。
备注:内容来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

