将基类对象分配给派生类

时间:2011-10-21 14:57:13

标签: c++ oop

考虑我正在创建两个类的对象:

BaseClass B;
DerievedClass D;

然后我在做:

B=D;
D=B;

哪个是合法的,为什么。这是一个C ++相关工作的面试官提出的问题。我知道大多数是B = D;将是有效的(对象切片);但它是这样D = B;只有在B有默认构造函数时才有效?是的,那为什么呢?

3 个答案:

答案 0 :(得分:6)

B=D;
D=B;

第一行将始终编译。第二行可能编译也可能不编译,因为它完全取决于你如何编写每个类。答案的其余部分将阐明它。请继续阅读。


  

是这样D = B;只有在B有默认构造函数时才有效吗?

没有

D=B仅在D已定义operator=作为参数时才有效。

B

或者,如果您在Derived & operator=(const Base &base); //member of Derived Base B; Derived D; D = B; //allowed - assignment 的初始化中执行此操作,则仅当D的构造函数将D作为参数时才有效。

B

Derived(const Base &base); //a constructor of Derived Base B; Derived D = B; //allowed - initialization 已将用户定义的转化定义为B

D

答案 1 :(得分:0)

纳瓦兹是对的。 B = D是合法的,因为D是BaseClass的一个实例,并且将通过编译器生成的BaseClass复制构造函数接受。

BaseClass::BaseClass( const BaseClass& other ) { ... } // Implicit

此复制构造函数将由DerivedClass继承,但在执行D = B时,编译器将查找DerivedClass(const BaseClass&)方法,该方法不存在。

DerivedClass::DerivedClass( const DerivedClass& other ); // Implicit
DerivedClass::BaseClass( const BaseClass& other );       // Inherited
DerivedClass::DerivedClass( const BaseClass &other );    // Not defined!

答案 2 :(得分:0)

如果没有看到类的实现,你就不能假设这两个中的任何一个都会编译!

第一种情况:B=D

除非B的=运算符已经过载,否则它将被编译,在这种情况下甚至B=B 可能是非法的。您可以说,如果B=B合法,那么B=D也是合法的,因为DBaseClass类的有效实例。

第二种情况:D=B

纳瓦兹已经对此进行了适当的讨论。但简而言之,您需要明确允许它。你可以:

  1. 定义相等的运算符:

    DerivedClass::operator=(const BaseClass& copy)

  2. 定义显式转化运算符:

    BaseClass::operator DerivedClass() const

  3. DerivedClass中添加一个接受BaseClass

    的构造函数

    DerivedClass::DerivedClass(const BaseClass&)

  4. 请注意,第二种和第三种溶液不应共存,第三种溶液通常应优先使用。只有在您无法修改类或者您想要转换为非类的类型的情况下,转换运算符才会存在。