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 more than once.  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.