我有这样的代码:
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,那么我必须在每个派生类中重复相同的代码.
注:我对抄袭的意图Base来Child是简单地复制那些成员共同既Base和Child(这将是所有的成员Base).即使在阅读了下面的所有答案之后,我也真的不明白为什么C++不允许这样做,特别是如果operator=在Base类中有明确的定义.
Mic*_*urr 13
该标准提供了12.8/10"复制类对象"中特定问题的原因(重点补充):
因为如果未由用户声明,则为类隐式声明复制赋值运算符,则基类复制赋值运算符始终由派生类的复制赋值运算符隐藏(13.5.3).
如此以来,有一个隐含声明operator=(const Child&)时,编译器执行的名称查找/重载决议Child::operator=(),将Base类的函数签名从未考虑过(它是隐藏的).
下面的代码是我从一开始就想要的行为,它编译,
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)
无论如何,我学到了很多东西.感谢所有在此发布答案的人.
您不能将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完全不同.
| 归档时间: |
|
| 查看次数: |
8171 次 |
| 最近记录: |