C++11中继承含保护空构造函数的派生类需显式实现默认构造/析构吗?
关于C++11派生类构造/析构的自动生成规则
好问题!咱们结合你的场景,一步步拆解C++11里派生类构造和析构的自动生成逻辑:
一、默认构造函数的情况
你的基类IVCounter提供了protected的空默认构造函数,对于派生类Derived:
- 如果完全省略默认构造函数的声明:编译器会自动为你生成一个合成默认构造函数。这个合成构造函数会自动调用基类的
protected默认构造(因为派生类有权访问基类的protected成员),效果和你显式写Derived() : IVCounter() {}完全一致。 - 如果显式写
Derived() = default;:这和编译器自动生成的合成构造函数是等价的,它明确告诉编译器“用默认规则生成构造”,代码更清晰,但功能上和省略没区别。 - 显式写
Derived() : IVCounter() {}:这是冗余的,因为编译器生成的构造已经会自动调用基类的默认构造,没必要手动写。
⚠️ 注意:如果你的派生类声明了其他带参数的构造函数,编译器就不会自动生成默认构造了——这时候如果你需要默认构造,就必须显式声明(可以用=default)。
二、析构函数的情况
你的基类IVCounter提供了public的虚析构函数,对于派生类Derived:
- 如果完全省略析构函数的声明:编译器会自动生成一个合成析构函数。因为基类的析构是虚的,这个合成析构也会自动成为虚析构,并且会在执行完毕后调用基类的虚析构,效果和你显式写
~Derived() {}完全一致。 - 如果显式写
~Derived() = default;:这和编译器自动生成的合成析构等价,同样是虚析构,功能上和省略没区别,但代码更明确。 - 显式写
~Derived() {}:同样是冗余的,而且没必要手动写——除非你需要在析构里加自定义逻辑(但你的场景里是空析构)。
最终结论
在你的场景下(派生类没有其他构造/析构逻辑,也没有声明其他构造函数):
- 完全可以省略默认构造和析构的声明,编译器会自动生成符合要求的函数;
- 如果你想让代码更清晰,也可以用
=default来显式声明,但这不是必须的; - 显式写空的构造/析构是冗余的,完全没必要。
举个最简洁的正确写法:
class Derived: public IVCounter<SomeType> { // 啥都不用写!编译器会自动生成默认构造和虚析构 };
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

