Using and Porting the GNU Compiler Collection (GCC)
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.
Using and Porting the GNU Compiler Collection (GCC)
Packaging copyright © 1988-2000 OAR Corporation Context copyright by each document's author. See Free Software Foundation for information.