Ok, maybe i'm too fatigued to think about the solution to this problem, I looked a lot about a similar problem on the internet but didn't find one. So here's my terrible code:
class X
{
public:
virtual const X& operator =( const X& ) = 0;
};
class Y : public X
{
public:
virtual const X& operator =( const X& x )
{
return *this;
}
};
class Z : public Y
{
};
int main_08(int argc, char* argv[])
{
Z z1;
Z z2;
z1 = z2;
return 0;
}
According to my expectations, code should run fine because since the assignment of class Z is not overridden, it should point to the assignment operator of Y which is defined. So when writing "z1 = z2", the assignment operator of its base class should be called. The code runs fine when I comment out this line
Instead, I get LNK2019 saying:
error LNK2019: unresolved external symbol "public: virtual class X const & __thiscall X::operator=(class X const &)" (??4X@@UAEABV0@ABV0@@Z) referenced in function "public: class Y & __thiscall Y::operator=(class Y const &)" (??4Y@@QAEAAV0@ABV0@@Z)
I am puzzled and can't figure out how virtual function routing mechanism has made me call X::operator =( const X& ). Any thoughts?
Y
doesn't have a copy assignment operator. It has an assignment operator from X
, but that's not the same thing. So the compiler generates one. The generated operator automatically invokes X
's assignment operator in a non-virtual manner, i.e. it actually wants to call X::operator=
, not whatever overrides it.
Z
also gets a generated assignment operator, which calls Y
's assignment operator. And so you get a reference to the actual implementation of X::operator=
, which you don't provide.
More fundamentally, though, assignment and hierarchies don't mix well. You will run into the slicing problem. Don't make classes that are part of a polymorphic hierarchy assignable (or copyable at all). It's just not a good idea.