______________________________________________________________________

  12   Special member functions                      [special]

  ______________________________________________________________________

1 [Note: the special member functions affect the way  objects  of  class
  type  are  created,  copied, and destroyed, and how values can be con­
  verted to values of other types.  Often such special member  functions
  are  called  implicitly.   The  implementation will implicitly declare
  these member functions for a class type when the programmer  does  not
  explicitly declare them.  ]

  +-------                 BEGIN BOX 1                -------+
  "Implicitly-declared  special  member  functions can be referred to in
  the same ways that user-declared functions are."  Is  this  true?   If
  the  user  does  not  declare  these functions, can these functions be
  explicitly called?  Can their address be taken?
  +-------                  END BOX 1                 -------+

2 Special member functions obey the usual access rules (_class.access_).
  [Example:  declaring a constructor protected ensures that only derived
  classes and friends can create objects using it.  ]

  12.1  Constructors                                        [class.ctor]

1 Constructors do not have names.  A special declarator syntax using the
  constructor's  class  name  followed  by  a  parameter list is used to
  declare the constructor in its class definition.  [Example:
          class C {
          public:
                  C(); // declares the constructor
          };
   --end example] A constructor is used to  initialize  objects  of  its
  class  type.   Because  constructors do not have names, they are never
  found during name lookup; however an explicit  type  conversion  using
  the functional notation (_expr.type.conv_) will cause a constructor to
  be called to initialize  an  object.   [Note:  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
  (_class.virtual_) or static (_class.static_).

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

3 Constructors are not inherited (_class.derived_).

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.

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
  (_intro.object_).   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.

  Before  the  implicitly-declared  default  constructor  for a class is
  implicitly defined, all the implicitly-declared  default  constructors
  for  its  base  classes and its nonstatic data members shall have been
  implicitly defined.

7 Default constructors are called implicitly to create class objects  of
  static    or    automatic    storage   duration   (_basic.stc.static_,
  _basic.stc.auto_) defined without  an  initializer  (_dcl.init_),  are
  called   to   create   class   objects  of  dynamic  storage  duration
  (_basic.stc.dynamic_) created by a new-expression in  which  the  new-
  initializer  is  omitted (_expr.new_), or are called when the explicit
  type conversion syntax (_expr.type.conv_) is used.

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

9 A copy constructor for a class X is a constructor with a first parame­
  ter  of type X& or of type const X&.  [Note: see _class.copy_ for more

  information on copy constructors.  ]

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

11No  return  type (not even void) shall be specified for a constructor.
  A return statement in the body of a constructor shall  not  specify  a
  return value.  The address of a constructor shall not be taken.

12A  constructor  can  be  used  explicitly to create new objects of its
  type, using the syntax
          class-name ( expression-listopt )
  [Example:
          complex zz = complex(1,2.3);
          cprint( complex(7.8,1.2) );
   --end example] An object created in  this  way  is  unnamed.   [Note:
  _class.temporary_  describes  the  lifetime  of  temporary objects.  ]
  [Note:  explicit  constructor  calls  do  not   yield   lvalues,   see
  _basic.lval_.  ]

13[Note:  some language constructs have special semantics when used dur­
  ing construction; see _class.base.init_ and _class.cdtor_.  ]

  12.2  Temporary objects                              [class.temporary]

1 While evaluating an expression, it might be  necessary  or  convenient
  for  an  implementation  to  generate temporary objects to hold values
  resulting from the  evaluation  of  the  expression's  subexpressions.
  During this evaluation, precisely when such temporaries are introduced
  is unspecified.  Even when the creation of  the  temporary  object  is
  avoided,  all  the  semantic  restrictions must be respected as if the
  temporary object was created.  [Example: even if the copy  constructor
  is  not  called,  all the semantic restrictions, such as accessibility
  (_class.access_), shall be satisfied.  ]

2 [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;

  alternatively, X(2) might be constructed in the space used to hold the
  argument.   Also,  a  temporary  might  be  used to hold the result of
  f(X(2)) before copying it to b using  X's  copy-constructor;  alterna­
  tively,  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.  ]

3 When  an  implementation introduces a temporary object of a class that
  has a non-trivial constructor (_class.ctor_), it shall ensure  that  a
  constructor  is  called  for  the  temporary  object.   Similarly, the
  destructor shall be called for a temporary with a non-trivial destruc­
  tor  (_class.dtor_).  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.

4 There are two contexts in which temporaries are destroyed at a differ­
  ent  point  than 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 initialization is com­
  plete.  The object is initialized from a copy of the temporary; during
  this copying, an implementation can call  the  copy  constructor  many
  times;  the temporary is destroyed after it has been copied, before or
  when the initialization completes.  If many temporaries are created by
  the  evaluation  of  the initializer, the temporaries are destroyed in
  reverse order of construction.

5 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  full
  expression  containing  the  call.   A  temporary  bound in a function
  return statement (_stmt.return_) persists until  the  function  exits.
  In  all these cases, the temporaries are destroyed in reverse order of
  construction.  In addition, the destruction of  temporaries  bound  to
  references  shall  take  into  account  the ordering of destruction of
  objects with static or automatic storage duration (_basic.stc.static_,
  _basic.stc.auto_);  that is, if obj1 is an object with static or auto­
  matic storage duration created before the temporary  is  created,  the
  temporary  shall  be destroyed before obj1 is destroyed; if obj2 is an
  object with static or automatic storage  duration  created  after  the
  temporary  is  created, the temporary shall be destroyed after obj2 is
  destroyed.

  12.3  Conversions                                         [class.conv]

1 Type conversions of class objects can be specified by constructors and
  by  conversion  functions.   These conversions are called user-defined
  conversions and are used for implicit type conversions  (_conv_),  for
  initialization   (_dcl.init_),   and  for  explicit  type  conversions
  (_expr.cast_, _expr.static.cast_).

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

3 [Note:  See _over.match_ for a discussion of the use of conversions in
  function 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.  [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))
          }
   --end example]

2 An explicit constructor constructs objects just like non-explicit con­
  structors, but does so only  where  the  direct-initialization  syntax
  (_dcl.init_)  or  where  casts  (_expr.static.cast_,  _expr.cast_) are
  explicitly used.  [Example:
          class Z {
          public:
                  explicit Z(int);
                  // ...
          };
          Z a1 = 1;        // error: no implicit conversion
          Z a3 = Z(1);     // ok: direct initialization syntax used
          Z a2(1);         // ok: direct initialization syntax used
          Z* p = new Z(1); // ok: direct initialization syntax used
          Z a4 = (Z)1;              // ok: explicit cast used
          Z a5 = static_cast<Z>(1); // ok: explicit cast used
   --end example]

  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 quali­
  fied) same object type (or a reference to it), or to a (possibly qual­
  ified)  base  class  of that type (or a reference to it).2) If conver­
  sion-type-id is void or cv-qualified void, the program is  ill-formed.

2 [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().   --end example]

3 User-defined conversions are not restricted to use in assignments  and
  initializations.  [Example:
          void g(X a, X b)
          {
              int i = (a) ? 1+a : 0;
              int j = (a&&b) ? a+b : i;
              if (a) { // ...
              }
          }
   --end example]

4 The conversion-type-id in a conversion-function-id is the longest pos­
  sible sequence of conversion-declarators.  [Note: this prevents  ambi­
  guities   between   the  declarator  operator  *  and  its  expression
  _________________________
  2)  Even  though  never  directly called to perform a conversion, such
  conversion operators can be declared and can  potentially  be  reached
  through a call to a virtual conversion operator in a base class

  counterparts.  [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.
  ] ]

5 Conversion operators are inherited.

6 Conversion functions can be virtual.

7 At  most  one user-defined conversion (constructor or conversion func­
  tion) is implicitly applied to a single value.  [Example:
          class X {
              // ...
          public:
              operator int();
          };
          class Y {
              // ...
          public:
              operator X();
          };
          Y a;
          int b = a;    // error:
                        // a.operator X().operator int() not tried
          int c = X(a); // ok: a.operator X().operator int()
   --end example]

8 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.  [Example:
          class X {
          public:
              // ...
              operator int();
          };
          class Y : public X {
          public:
              // ...
              operator void*();
          };
          void f(Y& a)
          {
              if (a) {    // error: ambiguous
                  // ...
              }
          }
   --end example]

  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).  The
  address of a destructor shall not  be  taken.   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.

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.

  Before  the  implicitly-declared  destructor for a class is implicitly
  defined, all the implicitly-declared destructors for its base  classes
  and its nonstatic data members shall have been implicitly defined.

5 A destructor for class X calls the destructors for X's direct members,
  the destructors for X's direct base classes and, if X is the  type  of
  the  most  derived class (_class.base.init_), its destructor calls the
  destructors for X's virtual  base  classes.   Bases  and  members  are
  destroyed  in the reverse order of the completion of their constructor
  (see _class.base.init_).  A  return  statement  (_stmt.return_)  in  a
  destructor  might  not directly return to the caller; before transfer­
  ring control to the caller, the destructors for the members and  bases
  are  called.   Destructors  for  elements  of  an  array are called in
  reverse order of their construction (see _class.init_).

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

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 [Note:  some language constructs have special semantics when used dur­
  ing destruction; see _class.cdtor_.  ]

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

9 Destructors  are  invoked implicitly (1) for a constructed object with
  static storage duration (_basic.stc.static_)  at  program  termination
  (_basic.start.term_),  (2)  for  a  constructed  object with automatic
  storage duration (_basic.stc.auto_) when the block in which the object
  is  created exits (_stmt.dcl_), (3) for a constructed temporary object
  when the lifetime of the temporary  object  ends  (_class.temporary_),
  (4)   for   a   constructed   object  allocated  by  a  new-expression
  (_expr.new_), through use of a delete-expression (_expr.delete_),  (5)
  in   several   situations   due   to   the   handling   of  exceptions
  (_except.handle_).  Destructors can also be invoked explicitly.

10A delete-expression invokes the destructor for the referenced  object;
  the object's memory location is then passed to a deallocation function
  (_expr.delete_, _class.free_).  [Example:
          class X {
              // ...
          public:
              X(int);
              ~X();
          };
          void g(X*);
          void f()        // common use:
          {
              X* p = new X(111);  // allocate and initialize
              g(p);
              delete p;           // cleanup and deallocate
          }
   --end example]

11[Note: explicit 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
          }
   --end note]

12Invocation  of  destructors  is  subject to the usual rules for member
  functions (_class.mfct_), e.g., an object of the appropriate  type  is
  required  (except  invoking  delete  on a null pointer has no effect).
  Once a destructor is invoked for  an  object,  the  object  no  longer
  exists;  the behavior is undefined if the destructor is invoked for an
  object whose lifetime has  ended  (_basic.life_).   [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.  ]

13The  notation  for  explicit  call of a destructor can be used for any
  scalar type name.  Using the notation for a type that does not have  a
  destructor  has  no effect.  [Note: allowing this makes it possible to
  write code without having to know if a destructor exists for  a  given
  type.  [Example:
          int* p;
          // ...
          p->int::~int();
   --end example]  --end note]

14
  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 new-expression is used to create an object of class T (or array
  thereof),  the  allocation function is looked up in the scope of class
  T; if no allocation function is found, the global allocation  function
  is used (_basic.stc.dynamic.allocation_).

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

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

5 [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
          }
   --end example]

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 (_basic.stc.dynamic.deallocation_).

7 When  a delete-expression is used to deallocate an array of objects of
  class T, the deallocation function to be called is determined by look­
  ing  up the name of operator delete[] in the scope of class T.  If the
  result of this lookup is ambiguous or  inaccessible,  the  program  is
  ill-formed.   If  no deallocation function is found in that scope, the
  global  deallocation  function  (_basic.stc.dynamic.deallocation_)  is
  used; see _expr.delete_.

8 When  a  delete-expression  is  used  to deallocate an object of class
  type, the deallocation function to be called is determined by  looking
  up  the  name of operator delete in the context of the outermost block
  of the destructor definition  (ignoring  any  names  defined  in  that
  block).4)  If  the  result of the lookup is ambiguous or inaccessible,
  the program is ill-formed.  If no deallocation function  is  found  in
  that       scope,      the      global      deallocation      function
  (_basic.stc.dynamic.deallocation_) is used; see _expr.delete_.

9 When a delete-expression is executed, the selected deallocation  func­
  tion  shall  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)

10Any  deallocation  function  for a class X is a static member (even if
  not explicitly declared static).  [Example:
  _________________________
  4)  This  applies to destructor definitions, not mere declarations.  A
  similar look up is not needed for the array version of the delete  op­
  erator  because  _expr.delete_  requires  that  in this situation, the
  static type of the delete-expression's operand be the same as its  dy­
  namic type.
  5)  If  the static type in the delete-expression is different from the
  dynamic type and the destructor is not virtual the size might  be  in­
  correct, but that case is already undefined; see _expr.delete_.

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

11Since member allocation and deallocation  functions  are  static  they
  cannot  be  virtual.   [Note:  however,  when the cast-expression of a
  delete-expression refers to an object of class type, because the deal­
  location  function  actually  called  is looked up in the scope of the
  destructor, 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 f()
          {
              B* bp = new D;
              delete bp;     //1: uses D::operator delete(void*)
          }
  Here,  storage  for  the non-array object of class D is deallocated by
  D::operator delete(), due to the virtual destructor.  ] [Note: virtual
  destructors  have  no  effect  on  the  deallocation function actually
  called when the cast-expression of a delete-expression  refers  to  an
  array of objects of class type.  For example,
          struct B {
              virtual ~B();
              void operator delete[](void*, size_t);
          };
          struct D : B {
              void operator delete[](void*, size_t);
          };
          void f(int i)
          {
              D* dp = new D[i];
              delete [] dp;  // uses D::operator delete[](void*, size_t)
              B* bp = new D[i];
              delete[] bp;   // undefined behavior
          }
   --end note]

12Access  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.  [Example:

  for the call on line //1 above, if B::operator delete() had been  pri­
  vate, the delete expression would have been ill-formed.  ]

  12.6  Initialization                                      [class.init]

1 If  T  is  either a class type or an array of class type, an object of
  type T is default-initialized (_dcl.init_) if:

  --the object has static storage duration and no initializer is  speci­
    fied in its declaration (see _dcl.init_), or

  --the object is created with a new-expression of the form new T() (see
    _expr.new_), or

  --the object is a temporary object created using the functional  nota­
    tion for type conversions T() (see _expr.type.conv_), or

  --the  object is a subobject, either a base of type T or a member m of
    type T, of a class object being created by a constructor that speci­
    fies  a  mem-initializer  of  the form T() or m(), respectively (see
    _class.base.init_).

2 Furthermore, if an object of class type T (or array thereof)

  --has automatic storage duration and no initializer  is  specified  in
    its declaration, or

  --is  created  with  a  new-expression with an omitted new-initializer
    (see _expr.new_), or

  --is a subobject, either a base of type T or a member m of type T  (or
    array thereof), of a class object created by a constructor that does
    not  specify  a  mem-initializer  for  T  or  m,  respectively  (see
    _class.base.init_),

  then  that  object (or, for an array, each element of the array) shall
  be initialized by the default constructor for T (and  the  initializa­
  tion is ill-formed if T has no accessible default constructor).

3 An  object of class type (or array thereof) can be explicitly initial­
  ized; see _class.expl.init_ and _class.base.init_.

4 When an array of class objects is initialized  (either  explicitly  or
  implicitly),  the  constructor shall be called for each element of the
  array,  following  the  subscript  order;  see  _dcl.array_.    [Note:
  destructors  for  the  array  elements  are called in reverse order of
  their construction.  ]

  12.6.1  Explicit initialization                      [class.expl.init]

1 An object of class  type  can  be  initialized  with  a  parenthesized
  expression-list, where the expression-list is construed as an argument
  list for a constructor  that  is  called  to  initialize  the  object.

  Alternatively,  a  single assignment-expression can be specified as an
  initializer using  the  =  form  of  initialization.   Either  direct-
  initialization  semantics  or copy-initialization semantics apply; see
  _dcl.init_.  [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
    --end  example]  [Note:  overloading  of  the  assignment   operator
  (_over.ass_) = has no effect on initialization.  ]

2 When  an  aggregate (whether class or array) contains members of class
  type  and  is  initialized  by   a   brace-enclosed   initializer-list
  (_dcl.init.aggr_),   each   such   member   is  copy-initialized  (see
  _dcl.init_) by the corresponding assignment-expression.  If there  are
  fewer  initializers in the initializer-list than members of the aggre­
  gate, each member not explicitly initialized shall be copy-initialized
  (_dcl.init_)  with  an initializer of the form T() (_expr.type.conv_),
  where T represents the  type  of  the  uninitialized  member.   [Note:
  _dcl.init.aggr_  describes  how  assignment-expressions in an initial­
  izer-list are paired with the aggregate members  they  initialize.   ]
  [Example:
          complex v[6] = { 1,complex(1,2),complex(),2 };
  Here,  complex::complex(double)  is  called  for the initialization of
  v[0] and v[3], complex::complex(double,double) is called for the  ini­
  tialization  of v[1], complex::complex() is called for the initializa­
  tion v[2], v[4], and v[5].  For another example,
          class X {
          public:
                  int i;
                  float f;
                  complex c;
          } x = { 99, 88.8, 77.7 };

  Here, x.i is initialized with 99, x.f is initialized  with  88.8,  and
  complex::complex(double)  is  called for the initialization of x.c.  ]
  [Note: braces can be elided in the initializer-list for any aggregate,
  even  if  the  aggregate has members of a class type with user-defined
  type conversions; see _dcl.init.aggr_.  ]

3 [Note: if T is a class type with no default constructor, any  declara­
  tion  of  an  object  of type T (or array thereof) is ill-formed if no
  initializer is explicitly specified (see _class.init_ and _dcl.init_).
  ]

4 [Note:  the  order  in  which objects with static storage duration are
  initialized is described in _basic.start.init_ and _stmt.dcl_.  ]

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

1 In the definition of a  constructor  for  a  class,  initializers  for
  direct  and  virtual base subobjects and nonstatic data members can be
  specified by a ctor-initializer, which has the form
          ctor-initializer:
                  : mem-initializer-list
          mem-initializer-list:
                  mem-initializer
                  mem-initializer , mem-initializer-list
          mem-initializer:
                  mem-initializer-id ( expression-listopt )
          mem-initializer-id:
                  ::opt nested-name-specifieropt class-name
                  identifier

2 Names in a mem-initializer-id are looked up in the scope of  the  con­
  structor's  class.   Unless  the  mem-initializer-id names a nonstatic
  data member of the constructor's class or a direct or virtual base  of
  that class, the mem-initializer is ill-formed.  A mem-initializer-list
  can initialize a base class using any  name  that  denotes  that  base
  class type.  [Example:
          struct A { A(); };
          typedef A global_A;
          struct B { };
          struct C: public A, public B { C(); };
          C::C(): global_A() { }    // mem-initializer for base A
   --end example] If a mem-initializer-id is ambiguous because it desig­
  nates both a direct non-virtual base class and  an  inherited  virtual
  base class, the mem-initializer is ill-formed.  [Example:
          struct A { A(); };
          struct B: public virtual A { };
          struct C: public A, public B { C(); };
          C::C(): A() { }           // ill-formed: which A?
    --end  example]  If  a ctor-initializer specifies more than one mem-
  initializer for the same member or base, the ctor-initializer is  ill-
  formed.

3 The  expression-list  in  a  mem-initializer is used to initialize the
  base class or nonstatic data member  subobject  denoted  by  the  mem-
  initializer-id.  The semantics of a mem-initializer are as follows:

  --if  the  expression-list of the mem-initializer is omitted, the base
    class or member subobject is default-initialized (see _dcl.init_);

  --otherwise, the subobject indicated by mem-initializer-id is  direct-
    initialized   using   expression-list   as   the   initializer  (see
    _dcl.init_).

  [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);
   --end example] There is a sequence  point  (_intro.execution_)  after
  the  initialization of each base and member.  The expression-list of a
  mem-initializer is evaluated as part of the initialization of the cor­
  responding base or member.

4 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.  After the call to a
  constructor for class X has completed, if a member  of  X  is  neither
  specified  in  the  constructor's mem-initializers, nor initialized in
  the body of the constructor, nor eligible for  default-initialization,
  the  member  has indeterminate value.  After the call to a constructor
  for class X has completed, if X has a nonstatic data member m that  is
  of const or reference type and if the member is neither specified in a
  mem-initializer nor eligible for default-initialization  (_dcl.init_),
  then m has an indeterminate value for the duration of its lifetime.

  +-------                 BEGIN BOX 2                -------+
  Should  the  standard mandate that const members and reference members
  be initialized in the ctor-initializer of their owning class?
  +-------                  END BOX 2                 -------+

5 Initialization shall proceed in the following order:

  --First, and only for the constructor of the  most  derived  class  as
    described  below,  virtual  base classes shall be initialized in the
    order they appear on a depth-first left-to-right  traversal  of  the
    directed acyclic graph of base classes, where "left-to-right" is the
    order of appearance of the base class names  in  the  derived  class
    base-specifier-list.

  --Then,  direct base classes shall be initialized in declaration order
    as they appear in the base-specifier-list (regardless of  the  order
    of the mem-initializers).

  --Then,  nonstatic data members shall be initialized in the order they
    were declared in the class definition (again regardless of the order
    of the mem-initializers).

  --Finally, the body of the constructor is executed.

  [Note:  the declaration order is mandated to ensure that base and mem­
  ber subobjects are destroyed in the reverse order  of  initialization.
  ]

6 If  a complete object (_intro.object_), a nonstatic data member, or an
  array element is of class type, its type, for  purposes  of  construc­
  tion, is considered the most derived class, to distinguish it from the
  class type of any base class subobject of the most derived class.  All
  sub-objects  representing  virtual base classes are initialized by the
  constructor of the most derived class.  If the constructor of the most
  derived  class  does  not specify a mem-initializer for a virtual base
  class V, then V's default constructor is called to initialize the vir­
  tual  base  class subobject.  If V does not have an accessible default
  constructor, the initialization is ill-formed.  A mem-initializer nam­
  ing a virtual base class shall be ignored during execution of the con­
  structor of any class that is not the most derived class.  [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()
   --end example]

7 Names in the expression-list of a mem-initializer are evaluated in the
  scope  of  the constructor for which the mem-initializer is specified.
  [Example:
          class X {
              int a;
              int b;
              int i;
              int j;
          public:
              const int& r;
              X(int i): r(a), b(i), i(i), j(this->i) {}
          };
  initializes X::r to refer to X::a, initializes X::b with the value  of
  the  constructor  parameter  i, initializes X::i with the value of the
  constructor parameter i, and initializes X::j with the value of  X::i;
  this  takes place each time an object of class X is created.  ] [Note:
  because the mem-initializer are evaluated in the  scope  of  the  con­
  structor,  the  this  pointer  can be used in the expression-list of a
  mem-initializer to refer to the object being initialized.  ]

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-initializer (or in a func­
  tion called directly or indirectly from a ctor-initializer) before all
  the mem-initializers for base classes have completed,  the  result  of
  the operation is undefined.  [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
          };
   --end example]

9 [Note:  Clause  _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 construction.  ]

  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.  [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;
  For another 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
                  { }
          };
   --end example]

2 To explicitly or implicitly convert a pointer (an lvalue) referring to
  an object of class X to a pointer (reference) to a direct or  indirect
  base  class  B of X, the construction of X and the construction of all
  of its direct or indirect bases that  directly  or  indirectly  derive
  from  B  shall have started and the destruction of these classes shall
  not have completed, otherwise  the  conversion  results  in  undefined
  behavior.  To form a pointer to (or access the value of) a direct non­
  static member of an object obj, the construction  of  obj  shall  have
  started  and  its  destruction shall not have completed, otherwise the

  computation of the pointer  value  (or  accessing  the  member  value)
  results in undefined behavior.  [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
                  { }
          };
   --end example]

3 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,
  and the object to which the call applies is the object under construc­
  tion or destruction, the function called is the  one  defined  in  the
  constructor  or destructor'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 refers to the object under construction or destruction  but
  its  type  is neither the constructor or destructor's own class or one
  of its bases, the result of the call is undefined.  [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
          }
   --end example]

4 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.

5 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.

6 [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
          }
   --end example]

  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 constructor for class X is a copy constructor if its first parameter
  is  of type X& or const X& and either there are no other parameters or
  else all other parameters have default arguments  (_dcl.fct.default_).
  [Example: X::X(const X&) and X::X(X&, int=1) are copy constructors.
          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);
    --end example] [Note: both forms of copy constructor may be declared
  for a class.  [Example:
          class X {
                  // ...
          public:
                  X(const X&);
                  X(X&); // OK
          };
   --end example]  --end note] [Note: if a class X only has a copy  con­
  structor  with  a parameter of type X&, an initializer of type const X
  cannot initialize  an  object  of  type  (possibily  cv-qualified)  X.
  [Example:
          struct X {
                  X();    // default constructor
                  X(X&);  // copy constructor with a nonconst parameter
          };
          const X cx;
          X x = cx;       // error -- X::X(X&) cannot copy cx into x
   --end example]  --end note]

3 A  declaration  of  a  constructor  for a class X is ill-formed if its
  first parameter is of type  (optionally  cv-qualified)  X  and  either
  there  are  no  other  parameters  or  else  all other parameters have
  default arguments.

  +-------                 BEGIN BOX 3                -------+
  Is a constructor with  a  parameter  of  type  volatile  X&  or  const
  volatile X& a copy constructor?  See 95-0056/N0656.
  +-------                  END BOX 3                 -------+

4 If  the  class definition does not explicitly declare a copy construc­
  tor, one is declared implicitly.  Thus, for the class definition
          struct X {
                  X(const X&, int);
          };
  a copy constructor is implicitly-declared.  If the user-declared  con­
  structor is later defined as
          X::X(const X& x, int i =0) { ... }
  then  any  use  of  X's  copy constructor is ill-formed because of the
  ambiguity; no diagnostic is required.

5 The implicitly-declared copy constructor for a class X will  have  the
  form
          X::X(const X&)
  if

  --each  direct  or  virtual  base  class B of X has a copy constructor
    whose first parameter is of type const B& and

  --for all the nonstatic data members of X that are of a class  type  M
    (or  array  thereof),  each  such  class type has a copy constructor
    whose first parameter is of type const M&.6)

  Otherwise, the implicitly declared copy constructor will have the form
          X::X(X&)

  +-------                 BEGIN BOX 4                -------+
  Must  an  implicitly-declared  copy constructor for class X be able to
  copy volatile objects of type X?  See 95-0056/N0656.
  +-------                  END BOX 4                 -------+

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

  +-------                 BEGIN BOX 5                -------+
  Question  1:  Should the standard require that the implicitly-declared
  copy  constructor  be  inline?   Question  2:  What  does  "can't   be
  _________________________
  6) This implies  that  the  reference  parameter  of  the  implicitly-
  declared  copy  constructor  cannot  bind  to  a  volatile lvalue; see
  _diff.special_.

  inherited" mean?  If D is derived from B, can you write D::B(const B&)
  to refer to B's copy constructor?
  +-------                  END BOX 5                 -------+

6 A copy constructor for class X is trivial if it is implicitly declared
  and if

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

  --each direct base class of X has a trivial copy constructor, and

  --for all the nonstatic data members of X that are of class  type  (or
    array thereof), each such class type has a trivial copy constructor;

  otherwise the copy constructor is non-trivial.

7 An implicitly-declared copy constructor is implicitly defined if it is
  used  to  initialize  an  object  of  its class type from a copy of an
  object of its class type or of a class type  derived  from  its  class
  type7).  [Note: the copy constructor is implicitly defined even if the
  implementation  elided  its  use  (_class.temporary_).  ] 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 or ambiguous copy constructor, or

  --a base class with an inaccessible or ambiguous copy constructor.

  Before the implicitly-declared copy constructor for a class is implic­
  itly defined, all implicitly-declared copy constructors for its direct
  and virtual base classes and its nonstatic  data  members  shall  have
  been implicitly defined.

8 The implicitly-defined copy constructor for class X performs a member­
  wise copy of its subobjects.  The order of copying is the same as  the
  order  of  initialization  of bases and members in a user-defined con­
  structor (see _class.base.init_).  Each subobject  is  copied  in  the
  manner appropriate to its type:

  --if  the  subobject  is  of  class type, the copy constructor for the
    class is used;

  --if the subobject is an array, each element is copied, in the  manner
    appropriate to the element type;

  --if  the subobject is of scalar or pointer-to-member type, the built-
    in assignment operator is used.
  _________________________
  7)  See _dcl.init_ for more details on direct and copy initialization.

  Virtual base class subobjects shall be copied only once by the implic­
  itly-defined copy constructor (see _class.base.init_).

9 A  user-declared copy assignment operator X::operator= is a non-static
  member function of class X with exactly one parameter of type X, X& or
  const  X&.   [Note: an overloaded assignment operator must be declared
  to have only one parameter; see _over.ass_.  ] [Note:  more  than  one
  form  of  copy  assignment  operator  may  be declared for a class.  ]
  [Note: if a class X only has a copy assignment operator with a parame­
  ter of type X&, an expression of type const X cannot be assigned to an
  object of type X.  [Example:
          struct X {
                  X()
                  X& operator=(X&);
          };
          const X cx;
          X x;
          x = cx; // error:
                  // X::operator=(X&) cannot assign cx into x
   --end example]  --end note]

  +-------                 BEGIN BOX 6                -------+
  Is an assignment operator with a parameter  of  type  volatile  X&  or
  const volatile X& a copy assignment operator?  See 95-0056/N0656.
  +-------                  END BOX 6                 -------+

10If  the class definition does not explicitly declare a copy assignment
  operator, one is declared implicitly.   The  implicitly-declared  copy
  assignment operator for a class X will have the form
          X& X::operator=(const X&)
  if

  --each  direct  base class B of X has a copy assignment operator whose
    parameter is of type const B& and

  --for all the nonstatic data members of X that are of a class  type  M
    (or array thereof), each such class type has a copy assignment oper­
    ator whose parameter is of type const M&.8)

  Otherwise, the implicitly declared copy constructor will have the form
          X& X::operator=(X&)

  +-------                 BEGIN BOX 7                -------+
  Must  an  implicitly-declared  copy assignment operator for class X be
  able to assign volatile objects of type X?  See 95-0056/N0656.
  +-------                  END BOX 7                 -------+

  _________________________
  8) This implies  that  the  reference  parameter  of  the  implicitly-
  declared  copy  assignment  operator cannot bind to a volatile lvalue;
  see _diff.special_.

  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.   An  implicitly-
  declared  copy  assignment  operator  is a public member of its class.
  Because a copy assignment operator is implicitly declared for a  class
  if  not declared by the user, a base class copy assignment operator is
  always hidden by the copy  assignment  operator  of  a  derived  class
  (_over.ass_).

  +-------                 BEGIN BOX 8                -------+
  Should  the standard require that the implicitly-declared copy assign­
  ment operator be inline?
  +-------                  END BOX 8                 -------+

11A copy assignment operator for class X is trivial if it is  implicitly
  declared and if

  --each  direct base class of X has a trivial copy assignment operator,
    and

  --for all the nonstatic data members of X that are of class  type  (or
    array  thereof),  each such class type has a trivial copy assignment
    operator;

  otherwise the copy assignment operator is non-trivial.

12An implicitly-declared copy assignment operator is implicitly  defined
  when an object of its class type is assigned a value of its class type
  or a value of a class type derived from its class type.  A program  is
  ill-formed  if  the  class  for  which  a  copy assignment operator 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.

  Before the implicitly-declared copy assignment operator for a class is
  implicitly defined, all implicitly-declared copy assignment  operators
  for  its direct base classes and its nonstatic data members shall have
  been implicitly defined.

13The implicitly-defined copy assignment operator for class  X  performs
  memberwise assignment of its subobjects.  The direct base classes of X
  are assigned first, in the order of their  declaration  in  the  base-
  specifier-list, and then the immediate nonstatic data members of X are
  assigned, in the order in which they were declared in the class  defi­
  nition.   Each  subobject is assigned in the manner appropriate to its

  type:

  --if the subobject is of class type, the copy assignment operator  for
    the class is used;

  --if  the subobject is an array, each element is assigned, in the man­
    ner appropriate to the element type;

  --if the subobject is of scalar or pointer-to-member type, the  built-
    in assignment operator is used.

  It is unspecified whether subobjects representing virtual base classes
  are assigned more than once by the implicitly-defined copy  assignment
  operator.  [Example:
          struct V {
          struct A : virtual V { };
          struct B : virtual V { };
          struct C : B, A { };
  it  is  unspecified  whether  the  virtual  base  class subobject V is
  assigned twice by the implicitly-defined copy assignment operator  for
  C.   --end example]

14[Note:  Copying  one object into another using the copy constructor or
  the copy assignment operator does not change the  layout  or  size  of
  either object.  ]

15Whenever a class object is copied and the original object and the copy
  have the same type, if the implementation can prove  that  either  the
  original  object  or  the  copy will never again be used except as the
  result of an implicit destructor call (_class.dtor_),  an  implementa­
  tion  is permitted to treat the original and the copy as two different
  ways of referring to the same object and not perform a  copy  at  all.
  In  that  case, the object is destroyed at the later of times when the
  original  and  the  copy  would  have  been  destroyed   without   the
  optimization.9) [Example:
          class Thing {
          public:
                  Thing();
                  ~Thing();
                  Thing(const Thing&);
                  Thing operator=(const Thing&);
                  void fun();
          };

  _________________________
  9)  Because  only one object is destroyed instead of two, and one copy
  constructor is not executed, there is still one object  destroyed  for
  each one constructed.

          void f(Thing t) { }
          void g(Thing t) { t.fun(); }

          int main()
          {
                  Thing t1, t2, t3;
                  f(t1);
                  g(t2);
                  g(t3);
                  t3.fun();
          }
  Here  t1  does not need to be copied when calling f because f does not
  use its formal parameter again after copying it. Although g  uses  its
  parameter,  the  call  to g(t2) does not need to copy t2 because t2 is
  not used again after it is passed to g.  On the other hand, t3 is used
  after passing it to g so calling g(t3) is required to copy t3.  ]