Virtual destination operator
Given the code below, shouldn't be typing Calling B
, should n't Calling A
? Isn't it a runtime type of a
a B
, and hence a virtual call should result in a call B::operator=
(since virtual calls are defined by the left-hand operand)?
#include <iostream>
class A
{
public:
virtual A& operator=(const A& a_) { std::cout << "Calling A" << std::endl; }
};
class B : public A
{
public:
virtual B& operator=(const B& b_) { std::cout << "Calling B" << std::endl; }
};
int main() {
B b1;
B b2;
A& a = b1;
a = b2; // Prints "Calling A", should be "Calling B"?
return 0;
}
source to share
a = b2;
- not a virtual call.
The reason for this is that it B::operator=(const B&)
doesn't override A::operator=(const A&)
because their signatures are different.
You can use override
to have the compiler automatically check these things for you.
Usage override
does two things:
- prevents such simple errors (the compiler is your best friend)
- makes the code easier to understand ("oh, so this function overrides something")
source to share
This method:
virtual B& operator=(const B& b_)
does not override this method:
virtual A& operator=(const A& a_)
To override a base class method, the child must have the same method signature.
The invocation A::operator=
does not postpone implementation to the derived class, because the derived class has no implementation virtual A& operator=(const A& a_)
.
source to share
First, as everyone said, your override is not - it's just an overload. Use the override keyword to confirm this.
The solution is to give the derived class operator exactly the same signature as the base class, taking A and dynamic_cast to B in the body.
You will need to think about what to do if the caller tries to assign A to B (i.e. the listing does not work). As Alf mentioned in a comment, it is for this reason that virtual assignment is not very popular.
source to share