Search code examples
c++classinitializationinitialization-list

When is an initialization list looked up by C++


I am trying to understand when the initialization list is referenced (involved) during base class and class non-static member instantiation. I have read this article and this article that summarizes the initialization order of a class (I have summarized it here)

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.

  • Finally, the body of the constructor is executed.

Now I understand by reading the above is that the base classes are created first and then the derived class. Also members are instantiated in the order they were declared in the class definition regardless of their position in the initialization list order.

This makes me think that every time a base class or a member variable during class instantiation is being instantiated (in the order specified above) C++ basically checks the initialization list of a class to see if any specific parameter or argument has been specified for that base class or member variable. If nothing has been specified then c++ does a default constructor call. Is my understanding correct. Please correct me if I am wrong.


Solution

  • Yes, you are correct1, when you don't initialize a base class or a non-static member in a member-initialization-list, or when you don't provide a member-initialization-list at all, the following applies:

    class.base.init/9

    In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then

    • if the entity is a non-static data member that has a default member initializer and either

      • the constructor's class is a union, and no other variant member of that union is designated by a mem-initializer-id or

      • the constructor's class is not a union, and, if the entity is a member of an anonymous union, no other member of that union is designated by a mem-initializer-id,

      -- the entity is initialized from its default member initializer as specified in [dcl.init];

    • otherwise, if the entity is an anonymous union or a variant member ([class.union.anon]), no initialization is performed;

    • otherwise, the entity is default-initialized.


    1: You said:

    ...If nothing has been specified then c++ does a default constructor call...

    To be somewhat pedantic, default initialized in the above quote doesn't always mean the default constructor will be called, take for example, in the case of non-class types like int whose default initialization depends on storage duration.