Implicit Copy-Assignment for Virtual Bases
------------------------------------------
When a base class is virtual, only one subobject of the base class
belongs to each full object. Also, the constructors and destructors are
invoked only once, and called from the most-derived class. However,
such objects behave unspecified when being assigned. For example:
struct Base{
char *name;
Base(char *n) : name(strdup(n)){}
Base& operator= (const Base& other){
free (name);
name = strdup (other.name);
}
};
struct A:virtual Base{
int val;
A():Base("A"){}
};
struct B:virtual Base{
int bval;
B():Base("B"){}
};
struct Derived:public A, public B{
Derived():Base("Derived"){}
};
void func(Derived &d1, Derived &d2)
{
d1 = d2;
}
The C++ standard specifies that `Base::Base' is only called once
when constructing or copy-constructing a Derived object. It is
unspecified whether `Base::operator=' is called more than once when the
implicit copy-assignment for Derived objects is invoked (as it is
inside `func' in the example).
g++ implements the "intuitive" algorithm for copy-assignment: assign
all direct bases, then assign all members. In that algorithm, the
virtual base subobject can be encountered many times. In the example,
copying proceeds in the following order: `val', `name' (via `strdup'),
`bval', and `name' again.
If application code relies on copy-assignment, a user-defined
copy-assignment operator removes any uncertainties. With such an
operator, the application can define whether and how the virtual base
subobject is assigned.