Member initializer list

< cpp‎ | language
Revision as of 20:21, 28 November 2013 by Cubbi (Talk | contribs)

C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Function declaration
Lambda function declaration
inline specifier
Exception specifications (deprecated)
noexcept specifier (C++11)
decltype (C++11)
auto (C++11)
alignas (C++11)
Storage duration specifiers
Alternative representations
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Attributes (C++11)
typedef declaration
Type alias declaration (C++11)
Implicit conversions - Explicit conversions
static_cast - dynamic_cast
const_cast - reinterpret_cast
Memory allocation
Class-specific function properties
Special member functions

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 )



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)
1) Initializes the base or member named by class-or-identifier using direct initialization or, if expression-list is empty, value- or default-initialization
2) Initializes the base or member named by class-or-identifier using list-initialization or aggregate-initialization
3) Initializes multiple bases using a pack expansion
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


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;
    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 constructor

If 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)

Initialization order

The order of member initializers in the list is irrelevant: the actual order of initialization is as follows:

1) If the constructor is for the most-derived class, virtual base classes are initialized in the order in which they appear in depth-first left-to-right traversal of the base class declarations (left-to-right refers to the appearance in base-specifier lists)
2) Then, direct base classes are initialized in left-to-right order as they appear in this class's base-specifier list
3) Then, non-static data members are initialized in order of declaration in the class definition.
4) Finally, the body of the constructor is executed

(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)


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()
      : Base ( 789 ),
        x ( 0 ),
        y ( 0 )
        // no exception
    catch (...)
        // exception occurred on initialization


  • 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]