What happens in the following example?
struct B { };
struct D1 : B { };
struct D2 : B { };
int main()
{
D1 d;
D2 d2;
B& x = d;
x = d2;
}
I know the reference is not re-assigned. x still refers to d, but then how can you assign d2 to d?
Some more:
struct B
{
B () { x = 0; }
int x;
virtual void foo () { cout << "B" << endl; }
};
struct D1 : B
{
D1 () { x = 1; }
virtual void foo () { cout << "D1" << endl; }
};
struct D2 : B
{
D2 () { x = 2; }
virtual void foo () { cout << "D2" << endl; }
};
int main()
{
D1 d;
D2 d2;
B& x = d;
x.foo(); //D1
//x.x is 1 here
x = d2;
x.foo(); //also D1
//but x.x is 2 here
}
It seems like x.x was updated, but the vftable was not… Why?
xrefers to theBbase class subobject ofd. The assignmentx = d2slices theBbase subobject fromd2and assigns its value to the subobject ofd.This is usually not done intentionally.
EDIT:
That is what the assignment operator
B::operator=does. Base classes in C++ are totally unaware that they are base classes. Also, the type of an object cannot ever be changed during its lifetime. The closest alternative is C++11’sstd::move, which can transfer the oldBobject inside aD1into a freshD2object. You would then destroy the old object.