Initialization Order of Class Data Members

Initialization Order of Class Data Members

The order is the order they appear in the class definition - this is from section 12.6.2 of the C++ Standard:

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 member subobjects
are destroyed in the reverse order of
initialization. ]

Order of member initialization list

Initialization of member variables occurs in the order that they are declared in the class.

http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-order

and:

http://en.cppreference.com/w/cpp/language/initializer_list

3) Then, non-static data members are initialized in order of
declaration in the class definition.

Order of In Class Initialization versus Constructor Initialization List

This is guaranteed by the standard that non-static data members will be initialized in the order of their declarations in the class definition. How they're initialized (via default member initializer or member initializer list) and the order of these initializers don't matter.

[class.base.init]#13.3

(13.3) - Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

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

That means, the initialization order will always be ptr -> m1 -> m2.

c++ class member initialization sequence

The rules for class initialization are spelled out in [class.base.init]/11

In a non-delegating constructor, initialization proceeds in the following order:

  • First, and only for the constructor of the most derived class (1.8), virtual base classes are 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 classes in the derived class base-specifier-list.

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

  • Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

8 Finally, the compound-statement of the constructor body is executed.

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

emphasis mine

So when we look at bullet 3 it specifically states that the member are constructed in the order the appear in the definition. This means that regardless of private, public, or how they are listed in the class member initialization list they will be constructed in the order they are declared.

Class member initialization order, C++

Whats the difference of written code and the one with same order in which they are declared???

If members don't depend on each other's initialization order, there is no difference whatsoever. But if they do, then a member initialization list may be telling a lie.

Many a programmer were bitten by this, when they thought their constructors were written correctly, but in fact they had undefined behavior on their hands.

Consider this simple case:

struct foo {
int _a;
int _b;
foo(int b) : _b(b), _a(2 * _b) {}
};

What's _a in the above example? If you answer anything but "the behavior is undefined because _b is used initialized", you'd be wrong.

Class member initialization order with class object as a member

Member variables are initialized in the order they are defined in the class. In your case bar will be initialized before foo (even if you change the order in the constructor initializer list).

What you're doing, using the uninitialized foo object, will lead to undefined behavior. There's no guarantee that a compiler will be able to catch it or even report it.

brace-or-equal-initializers initialization order

Yes, y is guaranteed to be initialized after x. Non-static data members are always initialized in order of their declaration in the class definition, regardless of how they're initialized (by member initializer list or default member initializer, even default initialization).

3) Then, non-static data member are initialized in order of
declaration in the class definition.

Why C++ forces initialization of member variables to be in the order of the declaration

Constructors could be overloaded while destructor can't. If data members could be initialized in different order for different constructors, then the destructor can't guarantee to perform destruction on data members in the reverse order of their construction (for objects constructed by different constructors).



Related Topics



Leave a reply



Submit