C++继承、转让
C++ inheritance, assignment
class Base{ ... } a, b;
class Derived{ ... } c, d;
a = c; // why does this work?
d = b; // and why doesn't this work?
d = static_cast<Derived>(b) // does this actually work?
将基类分配给派生类并反转时究竟会发生什么?
对于类类型,赋值是通过调用函数 operator=()
来完成的。如果您自己不声明,则将为您隐式声明复制赋值运算符;对于您的课程,这些看起来像:
Base::operator=(Base const &);
Derived::operator=(Derived const &);
因此,我们可以从任何Base
分配给Base
对象,包括派生类型。这就是第一行工作的原因。从派生类赋值(或初始化)有时称为切片:仅复制基子对象,而派生类将被忽略。
我们不能从Base
赋值给Derived
,因为它的隐式运算符需要一个Derived
。这就是第二行不起作用的原因,除非您要声明一个采用Base
参数的运算符。
第三行尝试创建一个从b
初始化的临时Derived
对象,然后将其分配给d
。当且仅当Derived
有一个转换构造函数采用类型 Base
的参数时,这将起作用。
C++中的公共继承(我假设您已经实现了)关系是"is-a"关系,因此Derived
是一个可能更专业的Base
。
a = c; // why does this work?
因此,为什么你可以将c
分配给a
似乎是合理的,因为c
是一个Derived
,但根据定义也是一个Base
。
d = b; // and why doesn't this work?
另一方面,你不能将Base
b
分配给Derived
d
,因为d
可能有成员,不能由Base
的构造函数初始化。
因为Derived
是从Base
派生出来的,所以Derived
是一个Base
,只是有额外的功能。因此,可以为Base
变量分配一个Derived
变量,但是,它将失去Derived
方法中引入的额外功能。
颠倒这个逻辑,Derived
不是Base
,它不止于此,所以你不能反过来分配,因为这会增加功能,而不是删除获得的东西。
至于最后一行,我不确定它是否会编译,但充其量如果它编译了,由于上述原因,您将具有未定义的行为。
请注意,我刚才所说的一些内容在进入虚拟继承时是错误的,但您现在不需要担心这一点。
将派生类的实例分配给基类的实例时,将分配所有基类成员。 a = c;
的实例时,它只会为派生类的成员分配一些未初始化的成员。 d = b;
因此,这是不可能的。
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 公共与私人继承
- 如何创建从同一类继承的不同对象的向量
- 如何从另一个文件继承私有成员变量和公共函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 带有继承的C++工厂
- 我应该避免多重实现继承吗
- C++继承更改成员
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 关于C++中具有多重继承"this"指针的说明
- 尝试使用继承和模板实现CRTP.Visual Studio正在生成编译器错误
- C++继承、转让