Given a pointer to an abstract base class A*
, I want to copy or assign it (as the base class) and have the derived copy constructor or assignment operator called. I understand copy constructors cannot be virtual, so presumably the copy constructor isn't an option for doing this, but the assignment operator is. Still, it doesn't seem to work: the following code prints
assigned a
x!
destroyed b
destroyed b
which fails to assign b.
#include <iostream>
using namespace std;
class A
{
public:
virtual void x()=0;
virtual ~A() {}
virtual A& operator=(const A& other) { cout << "assigned a" << endl; return *this;}
};
class B : public A
{
public:
virtual B& operator=(const B& other) { cout << "assigned b" << endl; return *this;}
virtual void x() { cout << "x!" << endl; }
virtual ~B() { cout << "destroyed b" << endl; }
};
int main()
{
A* a = new B();
A* aa = new B();
*aa=*a;
aa->x();
delete a;
delete aa;
return 0;
}
How to do this?
EDIT this question has been correctly answered below, but it was the wrong question. I shouldn't try to override the assignment operator because I don't want subclasses of A to assign to one another. For the simpler answer (hopefully) see C++ elegantly clone derived class by calling base class
The problem is that your B::operator=
does not override the one in A
. Change it to
virtual A& operator=(const A& other) { cout << "assigned b" << endl; return *this;}
and it will work. Also, try to use the override
keyword when overriding member functions (requires C++11). The code won't compile if you don't override. In your case, it would have caught your mistake
error: 'virtual B& B::operator=(const B&)' marked 'override', but does not override
PS: you were probably thinking about covariant return types. In order for it to work, the signature of your function has to be the same, except the return type. E.g., this will work:
virtual B& operator=(const A& other) { cout << "assigned b" << endl; return *this;}