In C++, class member variables are initialized in the order they are declared in the class, not in the order they appear in the constructor's initializer list. This can lead to subtle bugs, especially when one member depends on another during construction.
Key Rule
Regardless of the order used in the constructor's initializer list, the compiler initializes the members in the order they are declared in the class.
Example: Incorrect Assumption
#include <iostream> #include <string> class Example { std::string first; std::string second; public: Example() : second("Derived from: " + first), first("Initialized First") { std::cout << "first: " << first << "\n"; std::cout << "second: " << second << "\n"; } }; int main() { Example ex; return 0;
Output:
first: Initialized First
second: Derived from:
Even though first
is listed after second
in the initializer list, it is still initialized
before second
because it appears first in the class definition. As a result,
second
uses the default (empty) value of first
when constructing its own value.
Corrected Version
class Example { std::string second; std::string first; public: Example() : second("Derived from: " + first), first("Initialized First") {} };
In this corrected version, first
is declared after second
in the class,
so it is initialized after second
— still wrong!
To truly fix the issue, you must either:
- Reorder the declarations to place
first
beforesecond
, and - Ensure the constructor uses initializer list in the same logical order for clarity.
Takeaway
Always remember: C++ initializes class members in the order of declaration, not the initializer list order. This means the safest approach is to:
- Declare members in dependency order
- Match the constructor initializer list order with the declaration order