As I’m currently playing with C++, I come up to an issue. Code below:
#include <iostream>
class Base {
public:
virtual ~Base() {}
virtual Base& operator=(const Base& o)
{
std::cout << "Base operator called" << std::endl;
return *this;
}
};
class Derived : public Base {
public:
virtual ~Derived() {}
virtual Base& operator=(const Base& o)
{
std::cout << "Derived operator called" << std::endl;
return *this;
}
};
int main(void)
{
Derived a;
Derived b;
Base& c = a;
Base& d = b;
a = b; // Base called
a = static_cast<Base>(b); // Derived called
a = d; // Derived called
c = d; // Derived called
return (0);
}
The comment show what output I get.
The last 3 results are very much predictable, but I can’t understand the first.
As shown in the second one (static_cast), Derived::operator= is called when the right operand is a Base class. However, g++ (4.5.3-r2, gentoo Linux) success to understand that it must use the ‘Base’ class, but doesn’t go down the inheritance tree.
So I was expecting either Derived::operator= to be called, or g++ complaining for no “Derived& Derived::operator=(const Derived&)”. Could someone explain this behaviour to me ?
Thanks!
There is a compiler generated copy-assignment, i.e
operator=(Derived &)inDerivedclass, becauseDerived::operator=(Base const&)is not copy-assignment forDerived. This does not prevent compiler from generating the copy-assignment if you use assignment in your code.So this line:
calls the compiler generated
operator=(Derived &)forDerivedclass, which then calls theoperator=(Base const&). HenceBase calledis printed.Experiment: add this to
Derivedclass:Now,
a=bwill cause to print this:Note the order of printing also.
Hope that clarify your doubt.
Now this,
is functionally equivalent to this:
means,
a = ___generated_tmpcallsoperator=(Base const&), as the type of___generated_tmpisBase.And the rest two are pretty much clear, as you already seem to know.