首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++继承,赋值

C++继承,赋值
EN

Stack Overflow用户
提问于 2015-01-27 10:06:36
回答 4查看 578关注 0票数 2
代码语言:javascript
复制
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?

当将基类分配给派生类并反转时,会发生什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-01-27 10:21:10

对于类类型,分配是通过调用函数operator=()来完成的。如果您不自己声明,那么将为您隐式声明一个副本赋值操作符;对于您的类,如下所示:

代码语言:javascript
复制
Base::operator=(Base const &);
Derived::operator=(Derived const &);

因此,我们可以从任何Base对象(包括派生类型)分配给一个Base对象。这就是为什么第一行起作用了。从派生类分配(或初始化)有时称为切片:只有基子对象将被复制,派生类将被忽略。

我们不能从一个Derived分配给Base,因为它的隐式运算符需要一个Derived。这就是为什么第二行不能工作的原因,除非您声明一个接受Base参数的操作符。

第三行尝试创建一个从b初始化的临时b对象,然后将其分配给d。如果并且只有当Derived有一个接受Base类型参数的转换构造函数时,这个方法才能起作用。

票数 3
EN

Stack Overflow用户

发布于 2015-01-27 10:19:16

C++中的公共继承(我假设您已经实现了)关系是“is -a”-关系,所以Derived是可能更专门化的Base

代码语言:javascript
复制
a = c;  // why does this work?

因此,您为什么可以将c分配给a似乎是合理的,因为c是一个Derived,但从定义上来说也是一个Base

代码语言:javascript
复制
d = b;  // and why doesn't this work?

另一方面,您不能将Base b分配给Derived d,因为d可能有成员,不能由Base的构造函数初始化。

票数 2
EN

Stack Overflow用户

发布于 2015-01-27 10:20:24

由于Derived是从Base派生的,所以Derived a Base,只是具有附加功能。因此,可以为Base变量分配一个Derived变量,但是,它将失去Derived方法中引入的额外功能。

反其道而行之,Derived不是一个Base,它不仅仅是一个Base,所以您不能以相反的方式分配,因为这将增加功能,而不是删除所获得的功能。

至于最后一行,我不确定它是否会编译,但最好的情况是,出于上述原因,您将有未定义的行为。

请注意,我刚才说的一些在进入虚拟inheiritnace时是错误的,但是您现在不需要担心这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28167774

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档