Member initializer list
In the definition of a constructor of a class, specifies initializers for direct and virtual base subobjects and non-static data members. ( Not to be confused with std::initializer_list )
Contents |
[edit] Syntax
Appears as part of function definition syntax, for class constructors only, as the first part of the function body (before the opening brace of the compound statement)
The first character is the colon :
, followed by the comma-separated list of one or more member-initializers, each of which has the following syntax
class-or-identifier ( expression-list(optional) )
|
(1) | ||||||||
class-or-identifier brace-init-list | (2) | (since C++11) | |||||||
parameter-pack ...
|
(3) | (since C++11) | |||||||
class-or-identifier | - | any identifier, class name, or decltype expression that names a non-static data member, a direct or virtual base, or (for delegating constructors) the class itself |
expression-list | - | possibly empty, comma-separated list of the parameters to pass to the constructor of the base or member |
brace-init-list | - | brace-enclosed list of comma-separated initializers and nested braced-init-lists |
parameter-pack | - | name of a variadic template parameter pack |
[edit] Explanation
Before the compound statement that forms the function body of the constructor begins executing, initialization of all direct bases, virtual bases, and non-static data members is finished. Member initializer list is the place where non-default initialization of these objects can be specified. For members that cannot be default-initialized, such as members of reference and const-qualified types, member initializers must be specified.
The initializers where class-or-identifier names a virtual base class are ignored during execution of constructors of any class that is not the most derived class of the object that's being constructed.
Names that appear in expression-list or brace-init-list are evaluated in scope of the constructor:
class X { int a, b, i, j; public: const int& r; X(int i) : r(a) // initializes X::r to refer to X::a , b(i) // initializes X::b to the value of the parameter i , i(i) // initializes X::i to the value of the parameter i , j(this->i) // initializes X::j to the value of X::i { } };
Member functions (including virtual member functions) can be called from member initializers, but the behavior is undefined if not all direct bases are initialized at that point.
For virtual calls (if the bases are initialized), the same rules apply as the rules for the virtual calls from constructors and destructors: virtual member functions behave as if the dynamic type of *this is the class that's being constructed (dynamic dispatch does not propagate down the inheritance hierarchy) and virtual calls (but not static calls) to pure virtual member functions are undefined behavior.
If a non-static data member has an in-class brace-or-equal initializer and also appears in a member initializer list, then member initializer list is executed and brace-or-equal initializer is ignored: struct S { int n = 42; S() : n(7) {} // will set n to 7, not 42 }; |
(since C++11) |
Delegating constructorIf the name of the class itself appears as class-or-identifier in the member initializer list, then the list must consist of that one member initializer only; such constructor is known as the delegating constructor, and the constructor selected by the only member of the initializer list is the target constructor In this case, the target constructor is selected by overload resolution and executed first, then the control returns to the delegating constructor and its body is executed. Delegating constructors cannot be recursive. |
(since C++11) |
[edit] Initialization order
The order of member initializers in the list is irrelevant: the actual order of initialization is as follows:
(Note: if initialization order was controlled by the appearance in the member initializer lists of different constructors, then the destructor wouldn't be able to ensure that the order of destruction is the reverse of the order of construction)
[edit] Example
struct Class : public Base { int x; int y; Class ( int x ) : Base ( 123 ), // initialize base class x ( x ), // x (member) is initialized with x (parameter) y ( 0 ) // y initialized to 0 {} // empty constructor body Class ( double a ) : y ( a+1 ), x ( y ) // x will be initialized before y, this means that its value here is undefined {} // No base class constructor in list, this is the same as calling Base() Class() try : Base ( 789 ), x ( 0 ), y ( 0 ) { // no exception } catch (...) { // exception occurred on initialization } };
[edit] References
- C++11 standard (ISO/IEC 14882:2011):
-
- 12.6.2 Initializing bases and members [class.base.init]
- C++98 standard (ISO/IEC 14882:1998):
-
- 12.6.2 Initializing bases and members [class.base.init]