继承场景下编译器生成与用户自定义默认构造函数的差异及编译报错原因
两段代码的编译差异解析
咱们来拆解一下你遇到的这个问题:两段代码里Base类的私有构造函数是一样的,main函数也都没创建对象,但一段编译通过,另一段报错,核心原因在于Derived类是否显式定义了构造函数,以及C++编译器对构造函数的生成和权限检查时机的规则。
第一段代码(无编译错误)
class Base { private: Base() { cout << "Base constructor" << endl; } }; class Derived:public Base { }; int main() { return 0; }
- 当你不给
Derived显式定义任何构造函数时,编译器会隐式声明一个默认构造函数,但这个构造函数的具体实现(也就是调用基类构造函数的代码)只有在它被实际调用的时候才会被编译器生成。 - 你的
main函数里完全没有创建Derived的对象,这个隐式声明的构造函数从来不会被用到,所以编译器根本不会去生成它的定义,自然也不会触发对Base私有构造函数的访问权限检查——毕竟这段代码连编译的必要都没有,所以整个程序能顺利通过编译。
第二段代码(编译报错)
class Base { private: Base() { cout << "Base constructor" << endl; } }; class Derived:public Base { public: Derived() { } }; int main() { return 0; }
- 当你显式定义了
Derived的构造函数Derived()时,编译器必须生成这个构造函数的完整代码。根据C++的规则,派生类的构造函数必须调用基类的构造函数(这里因为你没手动写,编译器会自动插入对Base默认构造函数的调用)。 - 这时候编译器就会去检查:
Derived的构造函数有没有权限访问Base的私有构造函数?答案是没有——私有成员只能被类自身的成员和友元访问,派生类是没有权限的。所以编译器直接抛出访问权限错误,导致编译失败。
简单总结一下:隐式声明的默认构造函数是"按需生成"的,没被调用就不会触发权限检查;而显式定义的构造函数必须完整生成,这时候就会立刻检查对基类构造函数的访问权限。
内容的提问来源于stack exchange,提问作者user2390140
相关产品推荐
相关产品推荐

