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?当将基类分配给派生类并反转时,会发生什么?
发布于 2015-01-27 10:21:10
对于类类型,分配是通过调用函数operator=()来完成的。如果您不自己声明,那么将为您隐式声明一个副本赋值操作符;对于您的类,如下所示:
Base::operator=(Base const &);
Derived::operator=(Derived const &);因此,我们可以从任何Base对象(包括派生类型)分配给一个Base对象。这就是为什么第一行起作用了。从派生类分配(或初始化)有时称为切片:只有基子对象将被复制,派生类将被忽略。
我们不能从一个Derived分配给Base,因为它的隐式运算符需要一个Derived。这就是为什么第二行不能工作的原因,除非您声明一个接受Base参数的操作符。
第三行尝试创建一个从b初始化的临时b对象,然后将其分配给d。如果并且只有当Derived有一个接受Base类型参数的转换构造函数时,这个方法才能起作用。
发布于 2015-01-27 10:19:16
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的构造函数初始化。
发布于 2015-01-27 10:20:24
由于Derived是从Base派生的,所以Derived 是a Base,只是具有附加功能。因此,可以为Base变量分配一个Derived变量,但是,它将失去Derived方法中引入的额外功能。
反其道而行之,Derived不是一个Base,它不仅仅是一个Base,所以您不能以相反的方式分配,因为这将增加功能,而不是删除所获得的功能。
至于最后一行,我不确定它是否会编译,但最好的情况是,出于上述原因,您将有未定义的行为。
请注意,我刚才说的一些在进入虚拟inheiritnace时是错误的,但是您现在不需要担心这个问题。
https://stackoverflow.com/questions/28167774
复制相似问题