我遇到了以下问题,向我证明我对C ++的工作知之甚少。
我使用带有纯虚函数的基类
class Base
...
和类型
的派生类class Derived : public Base{
private:
Foo* f1;
...
两者都实现了赋值运算符。除此之外,Derived的赋值运算符复制f1中的数据。在我的代码中,我创建了两个类Derived
的新实例Base* d1 = new Derived();
Base* d2 = new Derived();
如果我现在调用赋值运算符
*d1 = *d2;
未调用Derived的赋值运算符,并且不复制f1中的数据!只有我这样做才有效。
*dynamic_cast<Derived*>(d1) = *dynamic_cast<Derived*>(d2);
有人可以解释为什么赋值运算符没有超载吗?
谢谢!
答案 0 :(得分:4)
如果没有看到相关代码,很难说。这是一个有效的例子:
#include <iostream>
using namespace std;
class A {
public:
virtual A& operator=(A& a) {}
};
class B : public A {
public:
B& operator=(A& a) { cout << "B" << endl; }
};
int main() {
A* foo = new B();
A* bar = new B();
*foo = *bar;
return 0;
}
这将在运行时打印B
。
你可能做错的事情:
operator=
虚拟。operator=
作为签名,比父母的operator=
更具限制性,因此您实际上并未覆盖父级的定义。例如,如果您在上面的示例中将B& operator=(A& a) { cout << "B" << endl; }
更改为B& operator=(B& a) { cout << "B" << endl; }
,则不会再打印B
。答案 1 :(得分:3)
我对接受的答案有一些不同的看法。这基本上是More Effetive C++
第33项。因此,即使已接受的解决方案有效,我认为重要的是要揭示使赋值算子虚拟化所涉及的危险!
class Animal {
public:
virtual Animal& operator=(const Animal& rhs);
};
class Lizard: public Animal {
public:
virtual Lizard& operator=(const Animal& rhs);
};
class Chicken: public Animal {
public:
virtual Chicken& operator=(const Animal& rhs);
};
int main(){
Lizard l;
Chicken c;
Animal *pL = &l;
Animal *pC = &c;
*pL = *pC; // assigns chicken to a lizard.
}
答案 2 :(得分:1)
要使虚拟工作,您需要相同的签名。因此,如果operator=
const Derived&
类中的Derived
参数与基类中const Base&
参数上的operator=(const Base&)
参数不匹配,则表示{。}}}。 p>
这意味着您可以完成多态,但是您需要在派生类中使用{{1}}来执行此操作。