Class members are initialized in the order in which they are declared in the class, not the order in which they appear in the class initializer
list. To avoid errors caused by order-dependent initialization, the order of members in the initialization list should match the order in which
members are declared in a class.
The initialization order, as described here, is:
- If the constructor is for the most-derived class, virtual bases 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)
- Then, direct bases are initialized in left-to-right order as they appear in this class’s base-specifier list
- Then, non-static data members are initialized in order of declaration in the class definition.
Noncompliant code example
#include <iostream>
struct A {
A(int num) {
std::cout << "A(num = " << num << ")" << std::endl;
}
};
struct B {
int b;
};
class C : public A, B {
public:
int x;
int y;
C(int i) : B{i}, A{b}, y(i), x(y + 1) { } // Noncompliant
};
int main() {
C c(1); // Undefined behavior, might print "A(num = 0)"
std::cout << c.x << " " << c.y << std::endl; // might print "1 1"
}
Compliant solution
#include <iostream>
struct A {
A(int num) {
std::cout << "A(num = " << num << ")" << std::endl;
}
};
struct B {
int b;
};
class C : public A, B {
public:
int x;
int y;
C(int i) : A{i}, B{i}, x(i + 1), y(i) { }
};
int main() {
C c(1); // prints "A(num = 1)"
std::cout << c.x << " " << c.y << std::endl; // prints "2 1"
}