Reputation: 893
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!
Upvotes: 4
Views: 128
Reputation: 361402
There is a compiler generated copy-assignment, i.e operator=(Derived &)
in Derived
class, because Derived::operator=(Base const&)
is not copy-assignment for Derived
. This does not prevent compiler from generating the copy-assignment if you use assignment in your code.
So this line:
a = b; // Base called
calls the compiler generated operator=(Derived &)
for Derived
class, which then calls the operator=(Base const&)
. Hence Base called
is printed.
Experiment: add this to Derived
class:
Derived & operator=(Derived const & obj) : Base(obj)
{
std::cout << "copy-assignment called" << std::endl;
return *this;
}
Now, a=b
will cause to print this:
Base called
copy-assignment called
Note the order of printing also.
Hope that clarify your doubt.
Now this,
a = static_cast<Base>(b); /// Derived called
is functionally equivalent to this:
Base ___generated_tmp = static_cast<Base>(b);
a = ___generated_tmp;
means, a = ___generated_tmp
calls operator=(Base const&)
, as the type of ___generated_tmp
is Base
.
And the rest two are pretty much clear, as you already seem to know.
Upvotes: 3