12 - Special member functions [special]

-1- The default constructor (class.ctor), copy constructor and copy assignment operator (class.copy), and destructor (class.dtor) are special member functions. The implementation will implicitly declare these member functions for a class type when the program does not explicitly declare them, except as noted in class.ctor. The implementation will implicitly define them if they are used, as specified in class.ctor, class.dtor and class.copy. Programs shall not define implicitly-declared special member functions. Programs may explicitly refer to implicitly declared special member functions. [Example: a program may explicitly call, take the address of or form a pointer to member to an implicitly declared special member function.

struct A { };                   //  implicitly-declared  A::operator=
struct B : A {
	B& operator=(const B &);
};
B& B::operator=(const B& s) {
	this->A::operator=(s);  //  well-formed
	return *this;
}

--- end example] [Note: the special member functions affect the way objects of class type are created, copied, and destroyed, and how values can be converted to values of other types. Often such special member functions are called implicitly. ]

-2- Special member functions obey the usual access rules (clause 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 an optional function-specifier (dcl.fct.spec) followed by the constructor's class name followed by a parameter list is used to declare or define the constructor. In such a declaration, optional parentheses around the constructor class name are ignored. [Example:

class C {
public:
	C();                    //  declares the constructor
};

C::C() { }                      //  defines the constructor

--- end example]

-2- 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. ]

-3- A typedef-name that names a class is a class-name (dcl.typedef); however, a typedef-name that names a class shall not be used as the identifier in the declarator for a constructor declaration.

-4- A constructor shall not be virtual (class.virtual) or static (class.static). A constructor can be invoked for a const, volatile or const volatile object. A constructor shall not be declared const, volatile, or const volatile (class.this). const and volatile semantics (dcl.type.cv) are not applied on an object under construction. Such semantics only come into effect once the constructor for the most derived object (intro.object) ends.

-5- 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 constructor for class X, a default constructor is implicitly declared. An implicitly-declared default constructor is an inline public member of its class. A constructor is trivial if it is an implicitly-declared default constructor and if:

-6- Otherwise, the constructor is non-trivial.

-7- 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). The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with an empty mem-initializer-list (class.base.init) and an empty function body. If that user-written default constructor would be ill-formed, the program is ill-formed. 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. [Note: an implicitly-declared default constructor has an exception-specification (except.spec). ]

-8- 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. A program is ill-formed if the default constructor for an object is implicitly used and the constructor is not accessible (clause class.access).

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

-10- A copy constructor for a class X is a constructor with a first parameter of type X& or of type const X&. [Note: see class.copy for more information on copy constructors. ]

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

-12- No 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.

-13- A functional notation type conversion (expr.type.conv) can be used to create new objects of its type. [Note: The syntax looks like an explicit call of the constructor. ] [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. ]

-14- [Note: some language constructs have special semantics when used during construction; see class.base.init and class.cdtor. ]

-15- During the construction of a const object, if the value of the object or any of its subobjects is accessed through an lvalue that is not obtained, directly or indirectly, from the constructor's this pointer, the value of the object or subobject thus obtained is unspecified. [Example:

struct C;
void no_opt(C*);

struct C {
	int c;
	C() : c(0) { no_opt(this); }
};
const C cobj;

void no_opt(C* cptr) {
	int i = cobj.c * 100;   //  value of  cobj.c  is unspecified
	cptr->c = 1;
	cout << cobj.c * 100    //  value of  cobj.c  is unspecified
	     << '\n';
}

--- end example]

12.2 - Temporary objects [class.temporary]

-1- Temporaries of class type are created in various contexts: binding an rvalue to a reference (dcl.init.ref), returning an rvalue (stmt.return), a conversion that creates an rvalue (conv.lval, expr.static.cast, expr.const.cast, expr.cast), throwing an exception (except.throw), entering a handler (except.handle), and in some initializations (dcl.init). [Note: the lifetime of exception objects is described in except.throw. ] Even when the creation of the temporary object is avoided (class.copy), 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 (clause 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; 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. ]

-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 destructor (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 different 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 complete. 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 the completion of their construction.

-5- The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below. A temporary bound to a reference member in a constructor's ctor-initializer (class.base.init) persists until the constructor exits. A temporary bound to a reference parameter in a function call (expr.call) persists until the completion of the full expression containing the call. A temporary bound to the returned value in a function return statement (stmt.return) persists until the function exits. In all these cases, the temporaries created during the evaluation of the expression initializing the reference, except the temporary to which the reference is bound, are destroyed at the end of the full-expression in which they are created and in the reverse order of the completion of their construction. If the lifetime of two or more temporaries to which references are bound ends at the same point, these temporaries are destroyed at that point in the reverse order of the completion of their 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 automatic 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. [Example:

class C {
	//  ...
public:
	C();
	C(int);
	friend C operator+(const C&, const C&);
	~C();
};
C obj1;
const C& cr = C(16)+C(23);
C obj2;
the expression C(16)+C(23) creates three temporaries. A first temporary T1 to hold the result of the expression C(16), a second temporary T2 to hold the result of the expression C(23), and a third temporary T3 to hold the result of the addition of these two expressions. The temporary T3 is then bound to the reference cr. It is unspecified whether T1 or T2 is created first. On an implementation where T1 is created before T2, it is guaranteed that T2 is destroyed before T1. The temporaries T1 and T2 are bound to the reference parameters of operator+; these temporaries are destroyed at the end of the full expression containing the call to operator+. The temporary T3 bound to the reference cr is destroyed at the end of cr's lifetime, that is, at the end of the program. In addition, the order in which T3 is destroyed takes into account the destruction order of other objects with static storage duration. That is, because obj1 is constructed before T3, and T3 is constructed before obj2, it is guaranteed that obj2 is destroyed before T3, and that T3 is destroyed before obj1. ]

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 (clause 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 (clause class.access). Access control is applied after ambiguity resolution (basic.lookup).

-3- [Note: See over.match for a discussion of the use of conversions in function calls as well as examples below. ]

-4- At most one user-defined conversion (constructor or conversion function) 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]

-5- User-defined conversions are used implicitly only if they are unambiguous. 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. Function overload resolution (over.match.best) selects the best conversion function to perform the conversion. [Example:

class X {
public:
    //  ...
    operator int();
};
class Y : public X {
public:
    //  ...
    operator char();
};
void f(Y& a)
{
    if (a) {                    //  ill-formed:
                                //   X::operator   int()  or  Y::operator   char()
                                //  ...
    }
}

--- end example]

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 constructor 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 constructors, but does so only where the direct-initialization syntax (dcl.init) or where casts (expr.static.cast, expr.cast) are explicitly used. A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization (dcl.init). [Example:

class Z {
public:
	explicit Z();
	explicit Z(int);
	//  ...
};
Z a;                            //  OK: default-initialization performed
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]

-3- A copy-constructor (class.copy) is a converting constructor. An implicitly-declared copy constructor is not an explicit constructor; it may be called for implicit type conversions.

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. The type of a conversion function (dcl.fct) is ``function taking no parameter returning conversion-type-id.'' A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.*
[Footnote: Even though never directly called to perform a conversion, such conversion functions can be declared and can potentially be reached through a call to a virtual conversion function in a base class --- end foonote]

-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 shall not represent a function type nor an array type. The conversion-type-id in a conversion-function-id is the longest possible sequence of conversion-declarators. [Note: this prevents ambiguities between the declarator operator * and its expression 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 functions are inherited.

-6- Conversion functions can be virtual.

12.4 - Destructors [class.dtor]

-1- A special declarator syntax using an optional function-specifier (dcl.fct.spec) followed by ~ followed by the destructor's class name followed by an empty parameter list is used to declare the destructor in a class definition. In such a declaration, the ~ followed by the destructor's class name can be enclosed in optional parentheses; such parentheses are ignored. A typedef-name that names a class is a class-name (dcl.typedef); however, a typedef-name that names a class shall not be used as the identifier in the declarator for a destructor declaration.

-2- A destructor is used to destroy objects of its class type. 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 shall not be static. A destructor can be invoked for a const, volatile or const volatile object. A destructor shall not be declared const, volatile or const volatile (class.this). const and volatile semantics (dcl.type.cv) are not applied on an object under destruction. Such semantics stop being into effect once the destructor for the most derived object (intro.object) starts.

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

-4- Otherwise, the destructor is non-trivial.

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

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. [Note: an implicitly-declared destructor has an exception-specification (except.spec). ]

-6- 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. All destructors are called as if they were referenced with a qualified name, that is, ignoring any possible virtual overriding destructors in more derived 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 transferring 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).

-7- 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 virtual destructor, its destructor (whether user- or implicitly- declared) is virtual.

-8- [Note: some language constructs have special semantics when used during destruction; see class.cdtor. ]

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

-10- 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). A program is ill-formed if an object of class type or array thereof is declared and the destructor for the class is not accessible at the point of the declaration. Destructors can also be invoked explicitly.

-11- At the point of definition of a virtual destructor (including an implicit definition (class.copy)), non-placement operator delete shall be looked up in the scope of the destructor's class (basic.lookup.unqual) and if found shall be accessible and unambiguous. [Note: this assures that an operator delete corresponding to the dynamic type of an object is available for the delete-expression (class.free). ]

-12- In an explicit destructor call, the destructor name appears as a ~ followed by a type-name that names the destructor's class type. The invocation of a destructor is subject to the usual rules for member functions (class.mfct), that is, if the object is not of the destructor's class type and not of a class derived from the destructor's class type, the program has undefined behavior (except that invoking delete on a null pointer has no effect). [Example:

struct B {
	virtual ~B() { }
};
struct D : B {
	~D() { }
};
D D_object;
typedef B B_alias;
B* B_ptr = &D_object;

void f() {
	D_object.B::~B();               //  calls  B's destructor
	B_ptr->~B();                    //  calls  D's destructor
	B_ptr->~B_alias();              //  calls  D's destructor
	B_ptr->B_alias::~B();           //  calls  B's destructor
	B_ptr->B_alias::~B_alias();     //  error, no  B_alias  in class  B
}

--- end example] [Note: an explicit destructor call must always be written using a member access operator (expr.ref); in particular, the unary-expression ~X() in a member function is not an explicit destructor call (expr.unary.op). ]

-13- [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; }
struct X {
    //  ...
    X(int);
    ~X();
};
void f(X* p);
void g()                        //  rare, specialized use:
{
    char* buf = new char[sizeof(X)];
    X* p = new(buf) X(222);     //  use  buf[]  and initialize
    f(p);
    p->X::~X();                 //  cleanup
}

--- end note]

-14- 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. ]

-15- [Note: the notation for explicit call of a destructor can be used for any scalar type name (expr.pseudo). Allowing this makes it possible to write code without having to know if a destructor exists for a given type. For example,

typedef int I;
I* p;
//  ...
p->I::~I();

--- end note]

12.5 - Free store [class.free]

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

-2- [Example:

class Arena;
struct B {
    void* operator new(size_t, Arena*);
};
struct D1 : B {
};
Arena*  ap;
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]

-3- 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).

-4- If a delete-expression begins with a unary :: operator, the deallocation function's name is looked up in global scope. Otherwise, if the delete-expression is used to deallocate a class object whose static type has a virtual destructor, the deallocation function is the one found by the lookup in the definition of the dynamic type's virtual destructor (class.dtor).*

[Footnote: A similar lookup is not needed for the array version of operator delete because expr.delete requires that in this situation, the static type of the delete-expression's operand be the same as its dynamic type. --- end foonote]
Otherwise, if the delete-expression is used to deallocate an object of class T or array thereof, the static and dynamic types of the object shall be identical and the deallocation function's name is looked up in the scope of T. If this lookup fails to find the name, the name is looked up in the global scope. If the result of the lookup is ambiguous or inaccessible, or if the lookup selects a placement deallocation function, the program is ill-formed.

-5- When a delete-expression is executed, the selected deallocation function 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.*

[Footnote: If the static type in the delete-expression is different from the dynamic type and the destructor is not virtual the size might be incorrect, but that case is already undefined; see expr.delete. --- end foonote]

-6- Any deallocation function for a class X is a static member (even if not explicitly declared static). [Example:

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]

-7- Since 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 deallocation function actually called is looked up in the scope of the class that is the dynamic type of the object, 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]

-8- Access 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 private, the delete expression would have been ill-formed. ]

12.6 - Initialization [class.init]

-1- When no initializer is specified for an object of (possibly cv-qualified) class type (or array thereof), or the initializer has the form (), the object is initialized as specified in dcl.init. [Note: if the class is a non-POD, it is default-initialized. ]

-2- An object of class type (or array thereof) can be explicitly initialized; see class.expl.init and class.base.init.

-3- 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 aggregate, each member not explicitly initialized shall be default-initialized (dcl.init). [Note: dcl.init.aggr describes how assignment-expressions in an initializer-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 initialization of v[1], complex::complex() is called for the initialization 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 declaration 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 constructor's class and, if not found in that scope, are looked up in the scope containing the constructor's definition. [Note: if the constructor's class contains a member with the same name as a direct or virtual base class of the class, a mem-initializer-id naming the member or base class and composed of a single identifier refers to the class member. A mem-initializer-id for the hidden base class may be specified using a qualified name. ] 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 designates 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] A ctor-initializer may initialize the member of an anonymous union that is a member of the constructor's class. If a ctor-initializer specifies more than one mem-initializer for the same member, for the same base class or for multiple members of the same union (including members of anonymous unions), 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:


[Example:
struct B1 { B1(int); /* ... */ };
struct B2 { B2(int); /* ... */ };
struct D : B1, B2 {
    D(int);
    B1 b;
    const int 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 corresponding base or member.

-4- If a given nonstatic data member or base class is not named by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then

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 default-initialized, nor initialized during execution of the body of the constructor, the member has indeterminate value.

-5- Initialization shall proceed in the following order:

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

-6- All sub-objects representing virtual base classes are initialized by the constructor of the most derived class (intro.object). 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 virtual base class subobject. If V does not have an accessible default constructor, the initialization is ill-formed. A mem-initializer naming a virtual base class shall be ignored during execution of the constructor 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 constructor, 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 function 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: 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 (clause class), before the constructor begins execution and after the destructor finishes execution, referring 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 nonstatic 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 constructor (including from the mem-initializer for a data member) or from a destructor, and the object to which the call applies is the object under construction 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 most derived 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 from the mem-initializer for a data member) 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 construction 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 constructor (including from the mem-initializer for a data member) 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 most derived 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 non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (dcl.fct.default).*

[Footnote: Because a template constructor is never a copy constructor, the presence of such a template does not suppress the implicit declaration of a copy constructor. Template constructors participate in overload resolution with other constructors, including copy constructors, and a template constructor may be used to copy an object if it provides a better match than other constructors. --- end foonote]
[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: all 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 constructor with a parameter of type X&, an initializer of type const X or volatile 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. A member function template is never instantiated to perform the copy of a class object to an object of its class type. [Example:

struct S {
	template<typename T> S(T);
};

S f();

void g() {
	S a( f() ); //  does not instantiate member template 
}

--- end example]

-4- If the class definition does not explicitly declare a copy constructor, 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 constructor 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 Otherwise, the implicitly declared copy constructor will have the form
X::X(X&)
An implicitly-declared copy constructor is an inline public member of its class.

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

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 type*.

[Footnote: See dcl.init for more details on direct and copy initialization. --- end foonote]
[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: Before the implicitly-declared copy constructor for a class is implicitly defined, all implicitly-declared copy constructors for its direct and virtual base classes and its nonstatic data members shall have been implicitly defined. [Note: an implicitly-declared copy constructor has an exception-specification (except.spec). ]

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

Virtual base class subobjects shall be copied only once by the implicitly-defined copy constructor (see class.base.init).

-9- A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&.*

[Footnote: Because a template assignment operator is never a copy assignment operator, the presence of such a template does not suppress the implicit declaration of a copy assignment operator. Template assignment operators participate in overload resolution with other assignment operators, including copy assignment operators, and a template assignment operator may be used to assign an object if it provides a better match than other assignment operators. --- end foonote]
[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 parameter 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;
void f() {
	x = cx;                 //  error:
                                //   X::operator=(X&)  cannot assign  cx  into  x
}

--- end example]
--- end note]

-10- If 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 Otherwise, the implicitly declared copy constructor will have the form
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 operator is invoked, that is, the object assigned to. An implicitly-declared copy assignment operator is an inline 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). A using-declaration (namespace.udecl) that brings in from a base class an assignment operator with a parameter type that could be that of a copy-assignment operator for the derived class is not considered an explicit declaration of a copy-assignment operator and does not suppress the implicit declaration of the derived class copy-assignment operator; the operator introduced by the using-declaration is hidden by the implicitly-declared copy-assignment operator in the derived class.

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

otherwise the copy assignment operator is non-trivial.

-12- An 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:

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. [Note: an implicitly-declared copy assignment operator has an exception-specification (except.spec). ]

-13- The 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 definition. Each subobject is assigned in the manner appropriate to its type:

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- A program is ill-formed if the copy constructor or the copy assignment operator for an object is implicitly used and the special member function is not accessible (clause class.access). [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. ]

-15- Whenever a temporary class object is copied using a copy constructor, and this object and the copy have the same cv-unqualified type, an implementation 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, even if the class copy constructor or destructor have side effects. For a function with a class return type, if the expression in the return statement is the name of a local object, and the cv-unqualified type of the local object is the same as the function return type, an implementation is permitted to omit creating the temporary object to hold the function return value, even if the class copy constructor or destructor has side effects. In these cases, the object is destroyed at the later of times when the original and the copy would have been destroyed without the optimization.*

[Footnote: 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. --- end foonote]
[Example:
class Thing {
public:
	Thing();
	~Thing();
	Thing(const Thing&);
	Thing operator=(const Thing&);
	void fun();
};
Thing f() {
	Thing t;
	return t;
}

Thing t2 = f();
Here t does not need to be copied when returning from f. The return value of f may be constructed directly into the object t2. ]