Because only standard conversion sequences are considered when converting
to the left operand of an assignment operation ([over.best.ics]),
an expression x=y with a subexpression x of class type
is always interpreted as x.operator=(y).
Since a copy assignment operator is implicitly declared for a class
if not declared by the user ([class.copy.assign]),
a base class assignment operator function is always hidden by
the copy assignment operator function of the derived class.
Any assignment operator function, even the copy and move assignment operators,
can be virtual.
For a derived class D with a base class B
for which a virtual copy/move assignment has been declared,
the copy/move assignment operator in D does not override
B's virtual copy/move assignment operator.
[Example 1: struct B {virtualintoperator=(int);
virtual B&operator=(const B&);
};
struct D : B {virtualintoperator=(int);
virtual D&operator=(const B&);
};
D dobj1;
D dobj2;
B* bptr =&dobj1;
void f(){
bptr->operator=(99); // calls D::operator=(int)*bptr =99; // ditto
bptr->operator=(dobj2); // calls D::operator=(const B&)*bptr = dobj2; // ditto
dobj1 = dobj2; // calls implicitly-declared D::operator=(const D&)} — end example]