关于何时调用基类的复制构造函数,我们有以下形式:
DerivedClass ( const DerivedClass& obj ) : BaseClass ( obj )
{
// ...
}
我只是不明白为什么我们将派生类的对象传递给基类复制构造函数。
关于何时调用基类的复制构造函数,我们有以下形式:
DerivedClass ( const DerivedClass& obj ) : BaseClass ( obj )
{
// ...
}
我只是不明白为什么我们将派生类的对象传递给基类复制构造函数。
你还想通过什么?因为唯一的其他选择是从空中变出的魔法小马。
这是一个典型的“隐藏在对父级的引用后面的真实类型”的东西。基类的复制 ctor 具有签名base(const base&)
。它不关心您是否传递了最派生类型、半派生类型或基类型。它只看到它关心的部分,即base
,而没有其他内容,因此它可以正常工作。
当然,这只适用于使用公共继承派生的类型,这形成了两者之间的关系。
看起来对派生类对象的引用正在被传递,但实际上它将被隐式向上转换,这将产生对基类子对象的引用。
实际上,您引用的代码与此代码完全等效:
DerivedClass ( const DerivedClass& obj ) :
BaseClass ( static_cast<const BaseClass&>( obj ) )
{
// ...
后一个代码是完全合理的——它通过将一个对已构造的其他对象的基子对象的引用传递给基类子对象构造函数来调用它。
派生类的对象具有“派生类的属性”+“基类的属性”
当我们要创建派生类的副本时,我们调用派生类的复制构造函数。本质上,我们想将“派生类的属性”+“基类的属性”复制到新对象。
派生类属性的副本由派生类复制构造函数负责。要复制基类的属性,我们需要显式调用基类复制构造函数。
如果你没有,基类会从哪里复制?
ADerivedClass
是 a BaseClass
,因此它可以隐式转换为对 a 的引用BaseClass
并在BaseClass
复制构造函数中用于复制。
所以BaseClass(const BaseClass&)
负责复制 的成员BaseClass
并DerivedClass(const DerivedClass&)
负责复制 的成员DerivedClass
。
这样做可以避免在BaseClass
派生自它的每个类中复制复制构造函数中的复制代码,并避免在修改基类时损坏。