History of the issue:
In classic C++, class members were initialized only in the constructor initializer list. With C++11, it became possible to specify default values directly in the declaration within the class (member initializers) to improve code readability and safety.
Problem:
There are several ways to assign a value to a class member: directly in the declaration (in-class), through the constructor initializer list, and within the constructor body. Different methods affect performance and semantics; misunderstanding can lead to unnecessary copying or default destructors, issues with constants and references.
Solution:
class MyClass { int x = 42; };
class MyClass { const int y; MyClass(int val) : y(val) {} // otherwise, compilation error };
class MyClass { std::string s; MyClass() { s = "hello"; } // First default, then assignment };
Key features:
What will be the order of member initialization: in the order they are declared in the class or in the order in the initializer list?
The order of initialization is always that in which members are declared in the class, not in the order of initialization in the list. Violating this order is dangerous for dependent members.
class A { int x = 1; int y = 2; A() : y(10), x(20) {} }; // x is initialized before y, regardless of order in the list
Can a member constant be initialized inside the constructor body if it was not initialized in the list?
No. Constants are initialized only in the initializer list. Assignment in the constructor body results in a compilation error.
What happens if a default value for a member is set directly in the class via in-class initializer and it is overridden in the constructor initializer list?
The value from the constructor initializer list will be used. The default value is only utilized if the list specifies nothing.
class C { int x = 10; C() : x(20) {} // x will be equal to 20 };
A class works with a file. The file is declared as std::ofstream and initialized in the constructor body. Danger: with the default constructor, an invalid std::ofstream may be created, leading to file operation errors.
Pros:
Cons:
The file is initialized in the initializer list, blocking erroneous use of the file with an invalid state, while members with default data use in-class initializers.
Pros:
Cons: