Are assignment operators not overloaded, when called upon pointers of a base class?
I have encountered the following problem which proved to me that I know far too little about the workings of C++.
I use a base class with pure virtual functions
class Base
...
and a derived classes of type
class Derived : public Base{
private:
Foo* f1;
...
Both have assignment operators implemented. Among other things, the assignment operator for Derived copies the data in f1. In my code, I create two new instances of class Derived
Base* d1 = new Derived();
Base* d2 = new Derived();
If I now call the assignment operator
*d1 = *d2;
the assignment operat开发者_如何转开发or of Derived is not called, and the data in f1 is not copied! It only works if I do
*dynamic_cast<Derived*>(d1) = *dynamic_cast<Derived*>(d2);
Can someone explain why the assignment operators are not overloaded?
Thanks!
It's hard to say without seeing the relevant code. Here's an example that works:
#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;
}
This will print B
when run.
Things that you might be doing wrong:
- You might have forgotten to make
operator=
virtual in the base class. - You might have given the child's class
operator=
as signature that's more restrictive than that of the parent'soperator=
, so you're not actually overriding the parent's definition. For example if you changeB& operator=(A& a) { cout << "B" << endl; }
toB& operator=(B& a) { cout << "B" << endl; }
in the example above, it will no longer printB
.
I have some alternate perspective on the accepted answer. This is basically More Effetive C++
Item 33. So even though the accepted solution works, I think it is important to bring out the dangers involved in making assignment operator virtual!
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.
}
For virtual to work you need the same signature. So if your operator=
works on a const Derived&
parameter in your Derived
class that doesn't match the one that is working on a const Base&
parameter in your base class.
This means that you can accomplish polymorphism but you need to have an operator=(const Base&)
in your derived class to do so.
精彩评论