为何不应继承基类的复制与移动构造函数?
关于CWG2356中基类复制/移动构造函数不被继承的原因
CWG2356的规定是:
通过using声明引入派生类的基类复制和移动构造函数,在构造派生类对象时不应参与重载决议。
很多人会有疑问:从基类继承的其他构造函数,同样也只是初始化基类子对象,派生类成员仍需自行处理,那为啥偏偏复制和移动构造函数不能被继承?
核心原因在于复制/移动构造函数的特殊语义:
- 复制构造函数的设计初衷是创建一个与源对象完全同类型、状态一致的新对象。如果允许继承基类的复制构造函数,当你尝试用一个派生类对象构造另一个派生类对象时,继承来的基类复制构造函数会被调用——它只会初始化基类部分,派生类自身的成员要么被默认初始化,要么完全未初始化,这完全违背了用户调用复制构造函数的预期:用户想要的是完整复制整个派生类对象,而非仅复制基类子对象。
- 普通构造函数则不同,用户通过
using引入基类的普通构造函数时,通常是明确想利用它初始化基类部分,派生类的成员可以通过类内初始化、成员初始化列表等方式补充初始化,这种行为符合预期,不会产生语义混淆。
另外,从重载决议的角度看,如果允许基类复制构造函数参与派生类的重载决议,它会和派生类默认生成的复制构造函数(若用户未自定义)形成竞争,基类版本的匹配优先级可能导致意外调用,进一步加剧语义混乱。
内容的提问来源于stack exchange,提问作者Blackteahamburger
相关产品推荐
相关产品推荐

