An initializer list supplies values for instance variables when a constructor creates an object. It initializes members before the constructor body runs. section 6.6 section 8.11
The practical mistake is assuming members initialize in the written list order. C++ initializes them in declaration order, so a member that depends on later declarations can read uninitialized values and cause undefined behavior. Assigning members in the constructor body avoids that ordering error but performs initialization and later assignment. section 6.6
Declare dependent members in dependency order
A Person object builds full from title, first, middle, and last. Declare those source members before full, then initialize every member in that same dependency-aware order.
Listing 8.23 Validating a parameter using a private validator in an initializer list
class Person {
private:
std::string name;
int age;
static int validateAge(int age) { #1
if (age < 0)
throw std::invalid_argument("negative age");
return age;
}
public:
Person(const std::string& name, int age) :
name(name), age(validateAge(age)) {} #2
friend std::ostream& operator<<(std::ostream&, const Person&);
};
std::ostream& operator<<(std::ostream& o, const Person& p) {
o << p.name << " is " << p.age << " years old";
return o;
}
int main() {
Person joey("Joey", 27); #3
std::cout << joey << '\n';
return 0;
}
Use a private validator inside the initializer list when a constructor parameter must satisfy the class invariant before member initialization completes. section 8.11

