为什么不能将Base类对象分配给Derived类对象?

时间:2017-08-24 09:28:02

标签: c++ c++11 object inheritance derived-class

派生类对象可以在C ++中分配给基类对象

Derived d;
Base b = d; // It's Ok

但为什么基类对象可以分配给派生类对象

Base b;
Derived d = b; //Not Ok. Compiler give an error

修改:

很抱歉,这个问题实际上是在面试时提出来的。

5 个答案:

答案 0 :(得分:8)

继承是"是-a"关系,但它只是单向的

如果你有例如。

struct Base { /* ... */ };
struct Derived : Base { /* ... */ };

然后DerivedBase,但Base Derived

这就是为什么你可以用派生对象分配或初始化基类实例(但要注意object slicing),而不是相反。

答案 1 :(得分:8)

派生对象是一个基础对象,带有附加信息。

您可以从派生对象的基础部分初始化完整的基础对象,没问题。

但是如果你想只从一个基础对象构造一个派生对象,那么附加信息应该用什么来初始化?

如果要为其他信息提供默认值,可以通过声明Derived(Base const &)构造函数来实现。但由于它在一般情况下不起作用,因此不适合你。

答案 2 :(得分:3)

In general a C++ compiler will disallow the assignment of a object of a base class to a derived one as, in a sense, the derived class is a superset of the base class: i.e. it wouldn't know how to to deal with any members that are specific to the derived class.

That said, you can handcode such a possibility by an appropriate overload of the assignment operator and an appropriate constructor in the derived class.

Aside from perhaps overcomplicating the language, I don't see why a trivially copyable base class instance could not be assigned to a derived class that contains no additional members. But this is not implemented in any C++ standard at the time of my writing. Furthermore, to my mind at least, the consequence of having any uninitialised derived class members and bypassed derived class constructors doesn't require materially more consideration on the part of a programmer than the perils of object slicing if a derived class instance is assigned to a base class! In other words, I don't think the hackneyed retort "because it makes no sense" makes much sense in itself.

Reference: http://en.cppreference.com/w/cpp/types/is_trivially_copyable

答案 3 :(得分:2)

如果有一个公共继承b / w基类和派生类,那么这就是“是”关系。

在“是一个”中,关系是基础。

这里最重要的一点是“是一种关系”不是双向的。

即派生是一个基数,但基不是派生的。

假设我们有Shape和Circle这两个类。

Shape是基础,Circle公开继承自Shape。

所以,圆形是形状,但形状不是圆形

//main.cpp
#include <iostream>
#include <string>

using namespace std;

class Shape
{
private:
    int x;
public:
    Shape(int i):x{i}
    {
        cout << "Base constructor called " << endl; 
    }
};

class Circle : public Shape
{
private :
    string color;  
public : 
    Circle(int radius) : Shape{ radius } 
    {
        cout << "Derived constructor called " << endl;
    }
    Circle(int radius, string color) : Shape{ radius }, color{ color }  
    {
        cout << "Derived constructor called " << endl;
    }
};


int main()
{
    //This is valid .  since a circle is a shape 
    Circle s(1);
    Shape a = s;

    return 0; 
} 

但是您不能这样做,因为Shape不是圆形 这里的继承不是双向的

 Shape s(1);
 Circle a = s;

如果执行此操作,则会出现编译器错误

  no suitable user-defined conversion
        from "Shape" to "Circle" exists

答案 4 :(得分:-2)

如何使用临时引用?

Base b;
Derived d;
Base & d_ref = d;
d_ref = b;