296

I have a constructor that takes some arguments. I had assumed that they were initialized in the order listed, but in one case, it appears they were being initialized in reverse, resulting in an abort. When I reversed the arguments, the program stopped aborting.

Below is an example of the syntax I'm using. a_ needs to be initialized before b_ in this case. Can you ensure this order of initialization?

class A
{
  public:
    OtherClass a_;
    AnotherClass b_;

    A(OtherClass o, string x, int y)
      : a_(o)
      , b_(a_, x, y) {}
};
Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
hookenz
  • 36,432
  • 45
  • 177
  • 286

4 Answers4

334

It depends on the order of data member declarations in the class. So a_ will be the first one, then b_ will be the second one in your example.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
  • 32
    In fact, good compilers will warn if you have a different order in the declaration versus the constructor initialiser list. For example, see `-Wreorder` in gcc. – Greg Hewgill Aug 07 '09 at 04:17
  • 269
    The reason for which they are constructed in the member declaration order and not in the order in the constructor is that one may have several constructors, but there is only one destructor. And the destructor destroy the members in the reserse order of construction. – AProgrammer Aug 07 '09 at 06:45
  • 4
    did we mean ...reverse order of declaration. Not of "construction", the destructor cannot possibly see into the constructor to know can it? –  Nov 05 '18 at 15:09
222

To quote the standard, for clarification:

12.6.2.5

Initialization shall proceed in the following order:

...

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

...

GManNickG
  • 494,350
  • 52
  • 494
  • 543
31

The standard reference for this now appears to be 12.6.2 section 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).

Adam Getchell
  • 437
  • 4
  • 7
0

Seeing other answers without to much details into other members initialization I recommend reading more info from standard reference 12.6.2 section 13 (thanks @Adam Getchell for link):

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

(13.1) — 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.

(13.2) — 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).

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

(13.4) — Finally, the compound-statement of the constructor body is executed.

Terminology:

base-specifier-list - list of base classes for derived class. See section 10 of reference.
Example: class A : public virtual B, private C

mem-initializers - list of initializers for members of your class.
Example: A::A() : number(1.0f), text("abc"){ /* ... */}

compound-statement - block of {}, i.e. body of constructor.


That's all, simply said the order:

  1. static variables (see this stackoverflow question C++ static variables initialization order, also that interesting behavior SIOF). In single translation unit order follows declaration order, in different - compilers decide.
  2. virtual base classes as appear by dfs
  3. direct base classes as specified by order in deriving list
  4. non-static variables by declaration (! not initializers order) order
SolomidHero
  • 149
  • 2
  • 10