C++为什么我不能将基类分配给子类?

siv*_*udh 7 c++ inheritance

我有这样的代码:

class Base
{
public:
  void operator = (const Base& base_)
  {
  }
};

class Child : public Base
{
public:

};

void func()
{
  const Base base;
  Child child;
  child = base;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:既然Child派生自Base(因此它应该继承Base的operator =),那么该语句何时会出现

child = base;
Run Code Online (Sandbox Code Playgroud)

执行时,我得到一个像这样的编译器错误:

>.\main.cpp(78) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'const Base' (or there is no acceptable conversion)
1>        .\main.cpp(69): could be 'Child &Child::operator =(const Child &)'
1>        while trying to match the argument list '(Child, const Base)'
Run Code Online (Sandbox Code Playgroud)

我想要的行为是让Child类认识到它被分配了一个Base类,并且只是"自动"调用它的父类的operator =.

一旦我将此代码添加到Child类

void operator = (const Base& base_)
{
  Base::operator=(base_);
}
Run Code Online (Sandbox Code Playgroud)

然后一切都编好了.虽然我不认为这会很好,因为如果我有5个不同的类继承自Base,那么我必须在每个派生类中重复相同的代码.

注:我对抄袭的意图BaseChild是简单地复制那些成员共同BaseChild(这将是所有的成员Base).即使在阅读了下面的所有答案之后,我也真的不明白为什么C++不允许这样做,特别是如果operator=Base类中有明确的定义.

Mic*_*urr 13

该标准提供了12.8/10"复制类对象"中特定问题的原因(重点补充):

因为如果未由用户声明,则为类隐式声明复制赋值运算符,则基类复制赋值运算符始终由派生类的复制赋值运算符隐藏(13.5.3).

如此以来,有一个隐含声明operator=(const Child&)时,编译器执行的名称查找/重载决议Child::operator=(),将Base类的函数签名从未考虑过(它是隐藏的).


siv*_*udh 8

下面的代码是我从一开始就想要的行为,它编译,

class Base
{
public:
  void operator = ( const Base& base_)
  {
  }
};

class Child : public Base
{
};

void func()
{
  const Base base;

  Child child;

  child.Base::operator=(base);
}
Run Code Online (Sandbox Code Playgroud)

我从来不知道你可以明确地称之为:

  child.Base::operator=(base);
Run Code Online (Sandbox Code Playgroud)

无论如何,我学到了很多东西.感谢所有在此发布答案的人.


Pet*_*der 6

您不能将Base指定给Child,因为Child可能不是base.要使用典型的动物示例,您在这里拥有的是:

const Animal animal;
Dog dog;
dog = animal;
Run Code Online (Sandbox Code Playgroud)

但动物可能是一只猫,你肯定不能把猫分配给狗.

话虽这么说,你不可能反过来这样做:

const Dog dog;
Animal animal;
animal = dog;
Run Code Online (Sandbox Code Playgroud)

狗肯定是一种动物,但你有一个尺寸问题.animal占用sizeof(Animal)堆栈上的空间,但dog占用sizeof(Dog)空间,这两个数量可能不同.

在C++中使用多态时,您需要使用引用或指针.例如,以下是好的:

Dog* const dog;
Animal* animal;
animal = dog;
Run Code Online (Sandbox Code Playgroud)

这里,无论指向什么,指针的大小都是相同的,因此可以进行赋值.请注意,您仍需要维护正确的层次结构转换.即使使用指针,也不能将Base分配给Child,因为我之前解释的原因是:Base可能与Child完全不同.

  • 我明白你的意思了,但是狗的部分会发生什么事情,而动物没有指定?你可以设计一种语言来实现这种方式,但这里的根本问题是它没有任何意义. (2认同)