______________________________________________________________________

  12   Special member functions                      [special]

  ______________________________________________________________________

1 Some member functions are special in that they affect the way  objects
  of  a  class are created, copied, and destroyed, and how values can be
  converted to values of other types.  Often such special functions  are
  called implicitly.  Also, the compiler can generate instances of these
  functions  when  the  programmer  does  not  supply  them.   Compiler-
  generated  special  functions can be referred to in the same ways that
  programmer-written functions are.

2 These member functions obey the usual access  rules  (_class.access_).
  For  example,  declaring  a  constructor  protected  ensures that only
  derived classes and friends can create objects using it.

  12.1  Constructors                                        [class.ctor]

1 A member function with the same name as its class  is  called  a  con­
  structor;  it  is  used  to initialize objects of its class type.  For
  initialization of objects of class type see _class.init_.

2 A constructor can be invoked for a const, volatile or  const  volatile
  object.1)  A  constructor  shall  not  be declared const, volatile, or
  const volatile (_class.this_).  A constructor shall not be virtual  or
  static.

3 Constructors are not inherited.

4 A  default  constructor for a class X is a constructor of class X that
  can be called without an argument.  If there is no user-declared  con­
  structor  for  class  X, a default constructor is implicitly declared.
  An implicitly-declared default constructor is a public member  of  its
  class.   A  constructor  is  trivial  if  it is an implicitly-declared
  default constructor and if:

  --its class has no virtual functions (_class.virtual_) and no  virtual
    base classes (_class.mi_), and

  --all  the direct base classes of its class have trivial constructors,
    and

  --for all the nonstatic data members of its class that  are  of  class
    type  (or array thereof), each such class has a trivial constructor.
  _________________________
  1) Volatile semantics might or might not be used.

5 Otherwise, the constructor is non-trivial.

6 An implicitly-declared default constructor for a class is  implicitly-
  defined  when  it  is  used  to  create  an  object  of its class type
  (_basic.stc_).  A program is ill-formed  if  the  class  for  which  a
  default constructor is implicitly defined has:

  --a nonstatic data member of const type, or

  --a nonstatic data member of reference type, or

  --a  nonstatic  data  member  of class type (or array thereof) with an
    inaccessible default constructor, or

  --a base class with an inaccessible default constructor.2)

  +-------                 BEGIN BOX 1                -------+
  Should  it  be  specified more precisely at which point in the program
  the implicit definition is ill-formed? i.e.  is  something  like  this
  needed: "The declaration or expression causing the implicit definition
  is ill-formed" ?
  +-------                  END BOX 1                 -------+

7 A copy constructor for a class X is a  constructor  that  accepts  one
  parameter  of  type X& or of type const X&.  See _class.copy_ for more
  information on copy constructors.

8 _class.base.init_ describes the order in which constructors  for  base
  classes  and non-static members are called and describes how arguments
  can be specified for the calls to these constructors.

9 A union member cannot be of a class type (or array thereof) that has a
  non-trivial constructor.

10No  return type (not even void) can be specified for a constructor.  A
  return statement in the body of a  constructor  shall  not  specify  a
  return  value.   It is not possible to take the address of a construc­
  tor.

11A constructor can be used explicitly to  create  new  objects  of  its
  type, using the syntax
          class-name ( expression-listopt )
  For example,
          complex zz = complex(1,2.3);
          cprint( complex(7.8,1.2) );
  An object created in this way is unnamed.  _class.temporary_ describes
  the lifetime of temporary objects.
  _________________________
  2) When a default constructor for a derived class  is  implicitly  de­
  fined,  all the implicitly-declared default constructors for its bases
  and members are also implicitly defined (and this recursively for  the
  members' base classes and members).

12Some language constructs have special semantics when used during  con­
  struction; see _class.base.init_ and _class.cdtor_.

  12.2  Temporary objects                              [class.temporary]

1 In some circumstances it might be necessary or convenient for the com­
  piler to generate a temporary object.  Precisely when such temporaries
  are introduced is implementation dependent.  For example,
          class X {
              // ...
          public:
              // ...
              X(int);
              X(const X&);
              ~X();
          };

          X f(X);
          void g()
          {
              X a(1);
              X b = f(X(2));
              a = f(a);
          }
  Here,  an  implementation  might use a temporary in which to construct
  X(2) before passing it to f()  using  X's  copy-constructor;  alterna­
  tively,  X(2) might be constructed in the space used to hold the argu­
  ment.  Also, a temporary might be used to hold the result  of  f(X(2))
  before  copying  it  to  b  using X's copy-constructor; alternatively,
  f()'s result might be constructed  in  b.   On  the  other  hand,  the
  expression  a=f(a)  requires  a temporary for either the argument a or
  the result of f(a) to avoid undesired aliasing of a.  Even if the copy
  constructor  is  not  called,  all  the semantic restrictions, such as
  accessibility, shall be satisfied.

2 When a compiler introduces a temporary object of a class  that  has  a
  non-trivial  constructor  (_class.ctor_),  it shall ensure that a con­
  structor is called for the temporary object.  Similarly, the  destruc­
  tor  shall  be  called  for  a temporary with a non-trivial destructor
  (_class.dtor_).  Ordinarily, temporary objects are  destroyed  as  the
  last  step  in evaluating the full-expression (_intro.execution_) that
  (lexically) contains the point where they were created.  This is  true
  even if that evaluation ends in throwing an exception.

3 There are two contexts in which temporaries are destroyed at a differ­
  ent point then at the end of the full-expression.  The  first  context
  is  when  an  expression  appears  as  an initializer for a declarator
  defining an object.  In that context, the  temporary  that  holds  the
  result  of the expression shall persist until the object's initializa­
  tion is complete.  The object is initialized from a copy of the tempo­
  rary;  during  this  copying, an implementation can call the copy con­
  structor many times; the temporary is destroyed as soon as it has been
  copied.

4 The  second  context is when a temporary is bound to a reference.  The
  temporary bound to the reference or the temporary containing the  sub-
  object that is bound to the reference persists for the lifetime of the
  reference initialized or until the end of the scope in which the  tem­
  porary  is  created,  which ever comes first.  A temporary holding the
  result of an initializer expression for a declarator that  declares  a
  reference  persists  until the end of the scope in which the reference
  declaration occurs.  A temporary bound to a reference in  a  construc­
  tor's  ctor-initializer  (_class.base.init_)  persists  until the con­
  structor exits.  A temporary bound to a reference parameter in a func­
  tion  call (_expr.call_) persists until the completion of the call.  A
  temporary bound in a function return  statement  (_stmt.return_)  per­
  sists until the function exits.

5 In  all cases, temporaries are destroyed in reverse order of creation.

  12.3  Conversions                                         [class.conv]

1 Type conversions of class objects can be specified by constructors and
  by conversion functions.

2 Such  conversions,  often  called  user-defined  conversions, are used
  implicitly in addition to standard conversions (_conv_).  For example,
  a function expecting an argument of type X can be called not only with
  an argument of type X but also with an argument of type T where a con­
  version  from  T to X exists.  User-defined conversions are used simi­
  larly for conversion of initializers (_dcl.init_), function  arguments
  (_expr.call_,   _dcl.fct_),  function  return  values  (_stmt.return_,
  _dcl.fct_),  expression  operands  (_expr_),  expressions  controlling
  iteration  and  selection statements (_stmt.select_, _stmt.iter_), and
  explicit type conversions (_expr.type.conv_, _expr.cast_).

3 User-defined conversions are applied only where they  are  unambiguous
  (_class.member.lookup_,   _class.conv.fct_).    Conversions  obey  the
  access control rules (_class.access_).   As  ever  access  control  is
  applied after ambiguity resolution (_class.scope_).

4 See  _over.match_  for a discussion of the use of conversions in func­
  tion calls as well as examples below.

  12.3.1  Conversion by constructor                    [class.conv.ctor]

1 A constructor declared without the  function-specifier  explicit  that
  can  be called with a single parameter specifies a conversion from the
  type of its first parameter to the type of its  class.   Such  a  con­
  structor is called a converting constructor.  For example,
          class X {
              // ...
          public:
              X(int);
              X(const char*, int =0);
          };

          void f(X arg)
          {
              X a = 1;         // a = X(1)
              X b = "Jessie";  // b = X("Jessie",0)
              a = 2;           // a = X(2)
              f(3);            // f(X(3))
          }

2 A  nonconverting  constructor  constructs objects just like converting
  constructors, but does so only where a constructor call is  explicitly
  indicated by the syntax.
          class Z {
          public:
                  explicit Z(int);
                  // ...
          };
          Z a1 = 1;        // error: no implicit conversion
          Z a3 = Z(1);     // ok: explicit use of constructor
          Z a2(1);         // ok: explicit use of constructor
          Z* p = new Z(1); // ok: explicit use of constructor

3 When  no converting constructor for class X accepts the given type, no
  attempt is made to find other constructors or conversion functions  to
  convert the assigned value into a type acceptable to a constructor for
  class X.  For example,
          class X {
          public:
                  X(int);
                  // ...
          };
          class Y {
          public:
                  Y(X);
                  // ...
          };

          Y a = 1;                 // illegal: Y(X(1)) not tried

  12.3.2  Conversion functions                          [class.conv.fct]

1 A member function of a class X with a name of the form
          conversion-function-id:
                  operator conversion-type-id
          conversion-type-id:
                  type-specifier-seq conversion-declaratoropt
          conversion-declarator:
                  ptr-operator conversion-declaratoropt
  specifies a conversion from X to the type specified by the conversion-
  type-id.   Such  member  functions  are  called  conversion functions.
  Classes, enumerations, and typedef-names shall not be declared in  the
  type-specifier-seq.   Neither  parameter  types nor return type can be
  specified.  A conversion operator is never used to convert a (possibly
  qualified)  object  (or  reference  to  an  object)  to  the (possibly

  qualified) same object type (or a reference to it), or to a  (possibly
  qualified)  base class of that type (or a reference to it). If conver­
  sion-type-id is void or cv-qualified void, the program is  ill-formed.

2 Here is an example:
          class X {
              // ...
          public:
              operator int();
          };
          void f(X a)
          {
              int i = int(a);
              i = (int)a;
              i = a;
          }
  In   all   three  cases  the  value  assigned  will  be  converted  by
  X::operator int().  User-defined conversions are not restricted to use
  in assignments and initializations.  For example,
          void g(X a, X b)
          {
              int i = (a) ? 1+a : 0;
              int j = (a&&b) ? a+b : i;
              if (a) { // ...
              }
          }

3 The conversion-type-id in a conversion-function-id is the longest pos­
  sible sequence of conversion-declarators.  This  prevents  ambiguities
  between the declarator operator * and its expression counterparts. For
  example:
          &ac.operator int*i; // syntax error:
                              // parsed as: '&(ac.operator int *) i'
                              // not as: '&(ac.operator int)*i'
  The * is the pointer declarator and not the multiplication operator.

4 Conversion operators are inherited.

5 Conversion functions can be virtual.

6 At most one user-defined conversion (constructor or  conversion  func­
  tion) is implicitly applied to a single value.  For example,
          class X {
              // ...
          public:
              operator int();
          };
          class Y {
              // ...
          public:
              operator X();
          };

          Y a;
          int b = a;    // illegal:
                        // a.operator X().operator int() not tried
          int c = X(a); // ok: a.operator X().operator int()

7 User-defined  conversions  are  used implicitly only if they are unam­
  biguous.  A conversion function in a derived class  does  not  hide  a
  conversion  function  in a base class unless the two functions convert
  to the same type.  For example,
          class X {
          public:
              // ...
              operator int();
          };
          class Y : public X {
          public:
              // ...
              operator void*();
          };
          void f(Y& a)
          {
              if (a) {    // error: ambiguous
                  // ...
              }
          }

  12.4  Destructors                                         [class.dtor]

1 A member function of class cl named ~cl is called a destructor; it  is
  used to destroy objects of type cl.  A destructor takes no parameters,
  and no return type can be specified for it (not even void).  It is not
  possible  to  take  the  address of a destructor.  A destructor can be
  invoked for a const, volatile or const volatile object.3) A destructor
  shall   not   be   declared   const,   volatile   or   const  volatile
  (_class.this_).  A destructor shall not be static.

2 If a class has no user-declared destructor, a destructor  is  declared
  implicitly.   An  implicitly-declared destructor is a public member of
  its class.  A destructor is trivial if it  is  an  implicitly-declared
  destructor and if:

  --all of the direct base classes of its class have trivial destructors
    and

  --for all of the non-static data members of  its  class  that  are  of
    class  type  (or  array  thereof),  each  such  class  has a trivial
    destructor.

3 Otherwise, the destructor is non-trivial.

  _________________________
  3) Volatile semantics might or might not be used.

4 An implicitly-declared destructor is  implicitly-defined  when  it  is
  used  to destroy an object of its class type (_basic.stc_).  A program
  is ill-formed if the  class  for  which  a  destructor  is  implicitly
  defined has:

  --a  non-static  data  member of class type (or array thereof) with an
    inaccessible destructor, or

  --a base class with an inaccessible destructor.4)

  +-------                 BEGIN BOX 2                -------+
  Should  it  be  specified more precisely at which point in the program
  the implicit definition is ill-formed?
  +-------                  END BOX 2                 -------+

5 Bases and members are destroyed in reverse of their construction  (see
  _class.expl.init_).   Destructors  for elements of an array are called
  in reverse order of their construction.

6 Destructors are not inherited.  A destructor can be  declared  virtual
  (_class.virtual_)  or  pure virtual (_class.abstract_); if any objects
  of that class or any derived class are created  in  the  program,  the
  destructor  shall be defined.  If a class has a base class with a vir­
  tual  destructor,  its   destructor  (whether  user-  or   implicitly-
  declared) is virtual.

7 Some  language  constructs  have  special  semantics  when used during
  destruction; see _class.cdtor_.

8 A union member cannot be of a  class  type  (or  array  thereof)  that
  requires a non-trivial destructor.

9 Destructors  are  invoked  implicitly  (1)  when an automatic variable
  (_basic.stc_) or temporary (_class.temporary_, _dcl.init.ref_)  object
  goes out of scope, (2) for constructed static (_basic.stc_) objects at
  program termination (_basic.start_), and (3) through use of a  delete-
  expression  (_expr.delete_)  for objects allocated by a new-expression
  (_expr.new_).  Destructors can also be invoked explicitly.  A  delete-
  expression invokes the destructor for the referenced object and passes
  the address of its memory to a deallocation  function  (_expr.delete_,
  _class.free_).  For example,
          class X {
              // ...
          public:
              X(int);
              ~X();
          };
  _________________________
  4) When a destructor for a derived class is  implicitly  defined,  all
  the implicitly-declared destructors for its bases and members are also
  implicitly defined (and this recursively for the members' base classes
  and members).

          void g(X*);
          void f()        // common use:
          {
              X* p = new X(111);  // allocate and initialize
              g(p);
              delete p;           // cleanup and deallocate
          }

10Explicit  calls  of  destructors  are  rarely needed.  One use of such
  calls is for  objects  placed  at  specific  addresses  using  a  new-
  expression  with the placement option.  Such use of explicit placement
  and destruction of objects can be necessary  to  cope  with  dedicated
  hardware  resources and for writing memory management facilities.  For
  example,
          void* operator new(size_t, void* p) { return p; }

          void f(X* p);

          static char buf[sizeof(X)];
          void g()        // rare, specialized use:
          {
              X* p = new(buf) X(222);  // use buf[]
                                       // and initialize
              f(p);
              p->X::~X();              // cleanup
          }

11Invocation of destructors is subject to the  usual  rules  for  member
  functions, e.g., an object of the appropriate type is required (except
  invoking delete on a null pointer has no effect).  When  a  destructor
  is invoked for an object, the object no longer exists; if the destruc­
  tor is explicitly invoked again for the same object  the  behavior  is
  undefined.   For example, if the destructor for an automatic object is
  explicitly invoked, and the block is subsequently  left  in  a  manner
  that  would  ordinarily invoke implicit destruction of the object, the
  behavior is undefined.

12The notation for explicit call of a destructor can  be  used  for  any
  simple type name.  For example,
          int* p;
          // ...
          p->int::~int();
  Using  the  notation for a type that does not have a destructor has no
  effect.  Allowing this enables people to write code without having  to
  know if a destructor exists for a given type.

13The  effect of destroying an object more than once is undefined.  This
  implies that that explicitly destroying a local variable causes  unde­
  fined behavior on exit from the block, because exiting will attempt to
  destroy the variable again.  This is true even if the block is  exited
  because of an exception.

  12.5  Free store                                          [class.free]

1 When  an object is created with a new-expression(_expr.new_), an allo­
  cation    function(operator new()    for    non-array    objects    or
  operator new[]()  for  arrays)  is  (implicitly)  called  to  get  the
  required storage (_basic.stc.dynamic.allocation_).

2 When a non-array object or an array of class T is created  by  a  new-
  expression, the allocation function is looked up in the scope of class
  T using the usual rules.

3 When a new-expression is executed, the  selected  allocation  function
  will  be  called with the amount of space requested (possibly zero) as
  its first argument.

4 Any allocation function for a class X is a static member (even if  not
  explicitly declared static).

5 For example,
          class Arena;  class Array_arena;
          struct B {
              void* operator new(size_t, Arena*);
          };
          struct D1 : B {
          };
          Arena*  ap;  Array_arena* aap;
          void foo(int i)
          {
              new (ap) D1;  // calls B::operator new(size_t, Arena*)
              new D1[i];    // calls ::operator new[](size_t)
              new D1;       // ill-formed: ::operator new(size_t) hidden
          }

6 When  an  object is deleted with a delete-expression(_expr.delete_), a
  deallocation function  (operator delete()  for  non-array  objects  or
  operator delete[]()  for arrays) is (implicitly) called to reclaim the
  storage occupied by the object.

7 When an object is deleted by  a  delete-expression,  the  deallocation
  function is looked up in the scope of class of the executed destructor
  (see _expr.delete_) using the usual rules.

8 When a delete-expression is executed, the selected deallocation  func­
  tion  will  be  called  with the address of the block of storage to be
  reclaimed as its first argument and (if  the  two-parameter  style  is
  used) the size of the block as its second argument.5)

9 Any  deallocation  function  for a class X is a static member (even if
  not explicitly declared static).  For example,
  _________________________
  5)  If the static class in the delete-expression is different from the
  dynamic class and the destructor is not virtual the size might be  in­
  correct, but that case is already undefined.

          class X {
              // ...
              void operator delete(void*);
              void operator delete[](void*, size_t);
          };
          class Y {
              // ...
              void operator delete(void*, size_t);
              void operator delete[](void*);
          };

10Since member allocation and deallocation  functions  are  static  they
  cannot be virtual.  However, the deallocation function actually called
  is determined by the destructor actually called, so if the  destructor
  is virtual the effect is the same.  For example,
          struct B {
              virtual ~B();
              void operator delete(void*, size_t);
          };
          struct D : B {
              void operator delete(void*);
              void operator delete[](void*, size_t);
          };
          void f(int i)
          {
              B* bp = new D;
              delete bp;     // uses D::operator delete(void*)
              D* dp = new D[i];
              delete [] dp;  // uses D::operator delete[](void*, size_t)
          }
  Here,  storage  for  the non-array object of class D is deallocated by
  D::operator delete(), due to the virtual destructor.

11Access to the deallocation function  is  checked  statically.   Hence,
  even though a different one might actually be executed, the statically
  visible deallocation function is required to be accessible.   Thus  in
  the  example  above,  if  B::operator delete()  had  been private, the
  delete expression would have been ill-formed.

  12.6  Initialization                                      [class.init]

  +-------                 BEGIN BOX 3                -------+
  This needs to be improved to talk about the behavior of  all  initial­
  izations;  operator  new  cannot  use an initializer-clause; temporary
  creation only uses default constructors.
  +-------                  END BOX 3                 -------+

1 When no explicit initialization is specified  when  creating  a  class
  object,  if  the  class  has a default constructor (_class.ctor_), the
  default constructor is used to initialize the object.  If  no  default
  constructor  exists for the class and the class has a non-trivial con­
  structor (_class.ctor_), the object shall be  explicitly  initialized.
  If  the class is an aggregate (_dcl.init.aggr_), an initializer-clause

  can be used; otherwise, a call to a user-declared constructor shall be
  specified.

2 Arrays  of  objects  of  class type use constructors in initialization
  (_class.ctor_) just as do individual objects.  If  the  array  is  not
  explicitly  initialized  and  the  class  has  a  default constructor,
  implicit initialization of the array elements occurs  by  calling  the
  default  constructor  for  each  element  of  the  array,  in order of
  increasing addresses (_dcl.array_).  If no default constructor  exists
  for  the  class and the class has a non-trivial constructor, the array
  shall be explicitly initialized.

  12.6.1  Explicit initialization                      [class.expl.init]

1 Objects of classes with user-declared constructors (_class.ctor_)  can
  be  initialized  with  a  parenthesized expression list.  This list is
  taken as the argument list for a call of a constructor doing the  ini­
  tialization.  Alternatively for declarations, a single value is speci­
  fied as the initializer using the = operator.  This value is  used  as
  the argument to a copy constructor (_class.ctor_, _class.copy_).  Typ­
  ically,  that  call  of  a  copy   constructor   can   be   eliminated
  (_class.temporary_).  For example,
          class complex {
              // ...
          public:
              complex();
              complex(double);
              complex(double,double);
              // ...
          };

          complex sqrt(complex,complex);
          complex a(1);             // initialize by a call of
                                    // complex(double)
          complex b = a;            // initialize by a copy of `a'
          complex c = complex(1,2); // construct complex(1,2)
                                    // using complex(double,double)
                                    // copy it into `c'
          complex d = sqrt(b,c);    // call sqrt(complex,complex)
                                    // and copy the result into `d'
          complex e;                // initialize by a call of
                                    // complex()
          complex f = 3;            // construct complex(3) using
                                    // complex(double)
                                    // copy it into `f'
          complex g = { 1, 2 };     // error; constructor is required
  Overloading of the assignment operator (_over.ass_) = has no effect on
  initialization.  See _dcl.init_ for the distinction between the paren­
  thesized and = forms of initialization.

2 If an array of class objects is initialized with an initializer-clause
  (_dcl.init.aggr_), each assignment-expression is treated as  an  argu­
  ment  in  a  constructor  call to initialize one element of the array,
  using the = form of initialization (_dcl.init_).  If there  are  fewer

  assignment-expressions  in the initializer-clause than elements in the
  array, the remaining elements are initialized using the  default  con­
  structor  for  the  class.  If there is no default constructor and the
  initializer-clause is incomplete, the array declaration is ill-formed.
  For example,
          complex v[6] = { 1,complex(1,2),complex(),2 };
  Here,  v[0]  and  v[3]  are initialized with complex::complex(double),
  v[1] is initialized with  complex::complex(double,double),  and  v[2],
  v[4], and v[5] are initialized with complex::complex().

3 The  order  in  which  static  objects are initialized is described in
  _basic.start.init_ and _stmt.dcl_.

  12.6.2  Initializing bases and members               [class.base.init]

1 The definition of a constructor can specify  initializers  for  direct
  and  virtual base classes and for nonstatic members not inherited from
  a base class.  This is most useful for class objects,  constants,  and
  references  where  the semantics of initialization and assignment dif­
  fer.  A ctor-initializer has the form
          ctor-initializer:
                  : mem-initializer-list
          mem-initializer-list:
                  mem-initializer
                  mem-initializer , mem-initializer-list
          mem-initializer:
                  ::opt nested-name-specifieropt class-name ( expression-listopt )
                  identifier ( expression-listopt )
  The argument list is used to initialize the named nonstatic member  or
  base  class object.  This (or for an aggregate (_dcl.init.aggr_), ini­
  tialization by a brace-enclosed list) is the only  way  to  initialize
  nonstatic const and reference members.  For example,
          struct B1 { B1(int); /* ... */ };
          struct B2 { B2(int); /* ... */ };

          struct D : B1, B2 {
              D(int);
              B1 b;
              const c;
          };
          D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4)
          { /* ... */ }

          D d(10);

2 If  class  X  has a member m of class type M and M has no default con­
  structor, then a definition of a constructor for class X is ill-formed
  if it does not specify a mem-initializer for m.

3
  +-------                 BEGIN BOX 4                -------+
  It  needs  to be made clear that the order specified below applies for
  user-declared  constructors  as  well   as   for   implicitly-declared

  constructors.
  +-------                  END BOX 4                 -------+

  First, the base classes are initialized in declaration order (indepen­
  dent of the order of mem-initializers), then the members are  initial­
  ized   in   declaration  order  (independent  of  the  order  of  mem-
  initializers), then the body of  D::D()  is  executed  (_class.ctor_).
  The  declaration  order is used to ensure that sub-objects and members
  are destroyed in the reverse order of initialization.

4 Virtual base classes constitute a special  case.   Virtual  bases  are
  constructed  before  any nonvirtual bases and in the order they appear
  on a depth-first left-to-right traversal of the directed acyclic graph
  of  base classes; left-to-right is the order of appearance of the base
  class names in the declaration of the derived class.

5 The class of a complete object (_intro.object_) is said to be the most
  derived  class  for  the  sub-objects representing base classes of the
  object.  All sub-objects for virtual base classes are  initialized  by
  the  constructor  of  the most derived class.  If a constructor of the
  most derived class does not specify a mem-initializer  for  a  virtual
  base class then that virtual base class shall have a default construc­
  tor.  Any mem-initializers for virtual classes  specified  in  a  con­
  structor  for a class that is not the class of the complete object are
  ignored.  For example,
          class V {
          public:
              V();
              V(int);
              // ...
          };
          class A : public virtual V {
          public:
              A();
              A(int);
              // ...
          };
          class B : public virtual V {
          public:
              B();
              B(int);
              // ...
          };
          class C : public A, public B, private virtual V {
          public:
              C();
              C(int);
              // ...
          };
          A::A(int i) : V(i) { /* ... */ }
          B::B(int i) { /* ... */ }
          C::C(int i) { /* ... */ }

          V v(1); // use V(int)
          A a(2); // use V(int)
          B b(3); // use V()
          C c(4); // use V()

6 A mem-initializer is evaluated in the  scope  of  the  constructor  in
  which it appears.  For example,
          class X {
              int a;
          public:
              const int& r;
              X(): r(a) {}
          };
  initializes X::r to refer to X::a for each object of class X.

7 The  identifier  of  a  ctor-initializer's mem-initializer in a class'
  constructor is looked up in the scope of the class.  It shall denote a
  nonstatic  data  member or the type of a direct or virtual base class.
  For the purpose of this name lookup, the name, if any, of  each  class
  is  considered  a  nested class member of that class.  A constructor's
  mem-initializer-list can initialize a base class using any  name  that
  denotes  that base class type; the name used can differ from the class
  definition. For example:
          struct A { A(); };
          typedef A global_A;
          struct B { };
          struct C: public A, public B { C(); };
          C::C(): global_A() { }    // calls A()
  A base class type in a ctor-initializer's  mem-initializer  shall  not
  designate  both  a direct non-virtual base class and an inherited vir­
  tual base class.  For example:
          struct A { A(); };
          struct B: public virtual A { };
          struct C: public A, public B { C(); };

          C::C(): A() { }           // ill-formed: which A?

8 Member functions (including virtual member functions, _class.virtual_)
  can  be called for an object under construction.  Similarly, an object
  under  construction  can  be  the  operand  of  the  typeid   operator
  (_expr.typeid_)  or of a dynamic_cast (_expr.dynamic.cast_).  However,
  if these operations are performed in a ctor-intializer (or in a  func­
  tion  called directly or indirectly from a ctor-intializer) before all
  the mem-initializers for base classes have completed,  the  result  of
  the operation is undefined.  For example:
          class A {
          public:
                  A(int);
          };

          class B : public A {
                  int j;
          public:
                  int f();
          B() : A(f()),           // undefined: calls member function
                                  // but base A not yet initialized
                  j(f()) { }      // well-defined: bases are all initialized
          };
          class C {
          public:
                  C(int);
          };
          class D : public B, C {
                  int i;
          public:
                  D() : C(f()),   // undefined: calls member function
                                  // but base C not yet initialized
                  i(f()) {}       // well-defined: bases are all initialized
          };

9 _class.cdtor_  describes  the result of virtual function calls, typeid
  and dynamic_casts during construction for the well-defined cases; that
  is,  describes  the  polymorphic behavior of an object under construc­
  tion.

  12.7  Construction and destruction                       [class.cdtor]

1 For an object of non-POD class type (_class_), before the  constructor
  begins  execution  and after the destructor finishes execution, refer­
  ring to any nonstatic member or base class of the  object  results  in
  undefined behavior.  For example,
          struct X { int i; };
          struct Y : X { };
          struct A { int a; };
          struct B : public A { int j; Y y; };
          extern B bobj;
          B* pb = &bobj;          // ok
          int* p1 = &bobj.a;      // undefined, refers to base class member
          int* p2 = &bobj.y.i;    // undefined, refers to member's member
          A* pa = &bobj;          // undefined, upcast to a base class type
          B bobj;                 // definition of bobj
          extern X xobj;
          int* p3 = &xobj.i;      // Ok, X is a POD class
          X xobj;

2 Example

          struct W { int j; };
          struct X : public virtual W { };
          struct Y {
                  int *p;
                  X x;
                  Y() : p(&x.j)    // undefined, x is not yet constructed
                  { }
          };

3 To  explicitly or implicitly convert a pointer to an object of class X
  to a pointer to a direct or indirect base class B, the construction of
  X  and  the  construction  of all of its direct or indirect bases that
  directly or indirectly derive from B and  which  are  also  direct  or
  indirect base classes of X6) shall have started and the destruction of
  these  classes  shall  not  have  completed, otherwise the computation
  results in undefined behavior.  To form a pointer  to  a  direct  non­
  static member of an object X given a pointer to X, the construction of
  X shall have started and the destruction of  X  shall  not  have  com­
  pleted,  otherwise the computation results in undefined behavior.  For
  example,
          struct A { };
          struct B : virtual A { };
          struct C : B { };
          struct D : virtual A { D(A*); };
          struct X { X(A*); };
          struct E : C, D, X {
                  E() : D(this),  // undefined: upcast from E* to A*
                                  // might use path E* -> D* -> A*
                                  // but D is not constructed
                  // D((C*)this), // defined:
                                  // E* -> C* defined because E() has started
                                  // and C* -> A* defined because
                                  // C fully constructed
                  X(this)         // defined: upon construction of X,
                                  // C/B/D/A sublattice is fully constructed
                  { }
          };

4 Member functions, including virtual functions  (_class.virtual_),  can
  be  called  during  construction  or  destruction (_class.base.init_).
  When a virtual function is called directly or indirectly from  a  con­
  structor  (including  from its ctor-initializer) or from a destructor,
  the function called is the one defined in the constructor or  destruc­
  tor's  own class or in one of its bases, but not a function overriding
  it in a class derived from the constructor or  destructor's  class  or
  overriding  it in one of the other base classes of the complete object
  (_intro.object_).  If the virtual function call uses an explicit class
  member access (_expr.ref_) and the object-expression's type is neither
  the constructor or destructor's own class or one  of  its  bases,  the
  _________________________
  6)  If  X  is  itself a base class, not all classes derived from B are
  necessarily base classes of X.

  result of the call is undefined.  For example,
          class V {
          public:
                  virtual void f();
                  virtual void g();
          };
          class A : public virtual V {
          public:
                  virtual void f();
          };
          class B : public virtual V {
          public:
                  virtual void g();
                  B(V*, A*);
          };
          class D : public A, B {
          public:
                  virtual void f();
                  virtual void g();
                  D() : B((A*)this, this) { }
          };
          B::B(V* v, A* a) {
                  f();    // calls V::f, not A::f
                  g();    // calls B::g, not D::g
                  v->g(); // v is base of B, the call is well-defined, calls B::g
                  a->f(); // undefined behavior, a's type not a base of B
          }

5 The typeid operator (_expr.typeid_) can be used during construction or
  destruction (_class.base.init_).  When typeid is used in a constructor
  (including  in  its ctor-initializer) or in a destructor, or used in a
  function  called  (directly  or  indirectly)  from  a  constructor  or
  destructor,  if  the operand of typeid refers to the object under con­
  struction or destruction, typeid yields the type_info representing the
  constructor or destructor's class.  If the operand of typeid refers to
  the object under construction or destruction and the  static  type  of
  the  operand  is neither the constructor or destructor's class nor one
  of its bases, the result of typeid is undefined.

6 Dynamic_casts (_expr.dynamic.cast_) can be used during construction or
  destruction (_class.base.init_). When a dynamic_cast is used in a con­
  structor (including in its ctor-initializer) or in  a  destructor,  or
  used  in a function called (directly or indirectly) from a constructor
  or destructor, if the operand of the dynamic_cast refers to the object
  under  construction  or destruction, this object is considered to be a
  complete object that has the type of the constructor  or  destructor's
  class.   If the operand of the dynamic_cast refers to the object under
  construction or destruction and the static type of the operand is  not
  a pointer to or object of the constructor or destructor's own class or
  one of its bases, the dynamic_cast results in undefined behavior.

7 Example

          class V {
          public:
                  virtual void f();
          };
          class A : public virtual V { };
          class B : public virtual V {
          public:
                  B(V*, A*);
          };
          class D : public A, B {
          public:
                  D() : B((A*)this, this) { }
          };
          B::B(V* v, A* a) {
                  typeid(this);   // type_info for B
                  typeid(*v);     // well-defined: *v has type V, a base of B
                                  // yields type_info for B
                  typeid(*a);     // undefined behavior: type A not a base of B
                  dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B
                                  // results in B*
                  dynamic_cast<B*>(a); // undefined behavior,
                                  // a has type A*, A not a base of B
          }

  12.8  Copying class objects                               [class.copy]

1 A  class  object  can  be  copied  in  two  ways,  by   initialization
  (_class.ctor_,  _dcl.init_),  including  for function argument passing
  (_expr.call_) and for function value return  (_stmt.return_),  and  by
  assignment  (_expr.ass_).   Conceptually,  these  two  operations  are
  implemented by a copy constructor (_class.ctor_) and  copy  assignment
  operator (_over.ass_).

2 A  copy constructor for a class X is a constructor whose first parame­
  ter is of type X& or const X& and whose other parameters, if any,  all
  have  default  arguments (_dcl.fct.default_), so that it can be called
  with a single argument of type X.   For  example,  X::X(const X&)  and
  X::X(X&, int=1) are copy constructors.

  +-------                 BEGIN BOX 5                -------+
  Should  the parameter of the implicitly-declared copy constructor have
  type const volatile X&?  See 94-0193R1/N0580R1.
  +-------                  END BOX 5                 -------+

          class X {
              // ...
          public:
              X(int);
              X(const X&, int = 1);
          };
          X a(1);         // calls X(int);
          X b(a, 0);      // calls X(const X&, int);
          X c = b;        // calls X(const X&, int);

3 A constructor for a class X whose first and only parameter is of  type
  (optionally cv-qualified) X is ill-formed.

4 If  there  is no user-declared copy constructor, a copy constructor is
  implicitly declared 7).

5 If all bases and members of a class X have copy constructors accepting
  const parameters, the implicitly-declared copy constructor for X has a
  single parameter of type const X&, as follows:
          X::X(const X&)
  Otherwise it has a single parameter of type X&8):
          X::X(X&)

6 An implicitly-declared copy constructor is  a  public  member  of  its
  class.  Copy constructors are not inherited.

7 An  implicitly-declared copy constructor is implicitly defined when it
  is used to copy an object of its class type.

  +-------                 BEGIN BOX 6                -------+
  We need to refer to subclauses that describe  when  class  copy  takes
  place.  Is the concept of trivial copy constructor needed?
  +-------                  END BOX 6                 -------+

  A  program  is ill-formed if the class for which a copy constructor is
  implicitly defined has:

  --a nonstatic data member of class type (or  array  thereof)  with  an
    inaccessible copy constructor, or

  --a base class with an inaccessible copy constructor. 9)

  +-------                 BEGIN BOX 7                -------+
  Should it be specified more precisely at which point  in  the  program
  the  implicit  definition  is  ill-formed? i.e. is something like this
  needed: "The first declaration or expression that does  a  class  copy
  causing  the  implicitly-declared  copy  constructor to be implicitly-
  _________________________
  7) Thus the class definition
          struct X {
              X(const X&, int);
          };
  causes a copy constructor to be  implicitly-declared  and  the  member
  function definition
          X::X(const X& x, int i =0) { ... }
  is ill-formed because of ambiguity.
  8)  In  this  case, programs that attempt initialization by copying of
  const X objects are ill-formed.
  9)  When a copy constructor for a derived class is implicitly defined,
  all the implicitly-declared copy constructors for the bases  and  mem­
  bers  are  also  implicitly defined (and this recursively for the mem­
  bers' base classes and members).

  defined is ill-formed" ?
  +-------                  END BOX 7                 -------+

8 The semantics of the implicitly-declared copy constructor are that  of
  memberwise  initialization of the base classes and nonstatic data mem­
  bers; memberwise initialization implies that if a class X has a member
  (or  array thereof) or base of a class M, M's copy constructor is used
  by X's implicitly-declared copy constructor for the initialization  of
  the  member or base M.  Objects representing virtual base classes will
  be initialized only once by the implicitly-declared copy  constructor.
  See  _class.expl.init_  for the order of initialization of members and
  bases.

9 A copy assignment operator operator= is a non-static  member  function
  of class X with exactly one parameter of type X&or const X&.  If there
  is no user-declared copy assignment operator, a copy assignment opera­
  tor is implicitly declared for class X.  If all bases and members of a
  class X have a copy assignment operators accepting  const  parameters,
  the  implicitly-declared  copy  assignment  operator for X will have a
  single parameter of type const X&, as follows:
          X& X::operator=(const X&)

  +-------                 BEGIN BOX 8                -------+
  Should the parameter of the implicitly-declared copy assignment opera­
  tor have type const volatile X&?  See 94-0193R1/N0580R1.
  +-------                  END BOX 8                 -------+

  Otherwise it will have a single parameter of type X&10):
          X& X::operator=(X&)
  The implicitly-declared copy assignment operator for class X  has  the
  return  type X&; it returns the object for which the assignment opera­
  tor is invoked, that is, the object assigned to 11).
  _________________________
  10) In this case, programs that attempt assignment by copying of const
  X objects will be ill-formed.
  11) Given the parameter type for the copy assignment operator, objects
  of  a  derived  class type can be assigned to objects of an accessible
  base class type.  For example,
          class X {
          public:
                  int b;
          };
          class Y : public X {
          public:
                  int c;
          };
          void f()
          {
                  X x1;
                  Y y1;
                  x1 = y1;    //1: ok
                  y1 = x1;    // error

10An implicitly-declared copy assignment operator is  a  public  of  its
  class.  Copy assignment operators are not inherited.

11An  implicitly-declared copy assignment operator is implicitly defined
  when an object of its class type is copied.

  +-------                 BEGIN BOX 9                -------+
  We need to refer to subclauses that describe  when  class  copy  takes
  place. Is the concept of trivial copy assignment operator needed?
  +-------                  END BOX 9                 -------+

  A program is ill-formed if the class for which a copy assignment oper­
  ator is implicitly defined has:

  --a nonstatic data member of const type, or

  --a nonstatic data member of reference type, or

  --a nonstatic data member of class type (or  array  thereof)  with  an
    inaccessible copy assignment operator, or

  --a base class with an inaccessible copy assignment operator 12)

  +-------                BEGIN BOX 10                -------+
  Should it be specified more precisely at which point  in  the  program
  the  implicit  definition  is  ill-formed? i.e. is something like this
  needed: "The first expression that does a class assignment causing the
  implicitly-declared  copy assignment operator to be implicitly-defined
  is ill-formed" ?
  +-------                 END BOX 10                 -------+

12The semantics of the implicitly-declared copy assignment operator  are
  that  of  memberwise assignment of the base classes and nonstatic data
  members; memberwise assignment implies that if a class X has a  member
  (or  array thereof) or base of a class M, M's copy assignment operator
  is used by X's implicitly-declared copy assignment  operator  for  the
  assignment of the member or base M.  Objects representing virtual base
  classes will be assigned only once by a the  implicitly-declared  copy
  assignment operator 13).
  _________________________
          }
  On line //1, y1.b is assigned to x1.b and y1.c is not copied.
  12)  When a copy assignment operator for a derived class is implicitly
  defined, all the implicitly-declared copy assignment operators for the
  bases  and  members  are also implicitly defined (and this recursively
  for the members' base classes and members).
  13)  Copying one object into another using the copy constructor or the
  copy assignment operator does not change the layout or size of  either
  object.  For example,
          struct s {
              virtual f();
              // ...

  +-------                BEGIN BOX 11                -------+
  This needs more work. See 94-0193R1/N0580R1.
  +-------                 END BOX 11                 -------+

  _________________________
          };

          struct ss : public s {
              f();
              // ...
          };
          void f()
          {
              s a;
              ss b;
              a = b;      // really a.s::operator=(b)
              b = a;      // error
              a.f();      // calls s::f
              b.f();      // calls ss::f
              (s&)b = a;  // assign to b's s part
                          // really ((s&)b).s::operator=(a)
              b.f();      // still calls ss::f
          }
  The  call  a.f()  will  invoke s::f() (as is suitable for an object of
  class s (_class.virtual_)) and the call b.f() will call ss::f() (as is
  suitable for an object of class ss).