В C++ порядок инициализации членов класса происходит всегда в том порядке, в каком они объявлены в теле класса, а не в том, в каком они указаны в списке инициализации конструктора.
Пример:
struct Foo { int a; int b; Foo() : b(2), a(b) {} };
В этом примере сначала будет инициализирован a значением неопределённой переменной b, потому что сначала инициализируется a, затем b, вне зависимости от порядка в списке инициализации. В итоге, a не будет равен 2.
Правильный способ: при инициализации ссылаться только на уже объявленные выше члены или использовать константы.
В каком порядке будут инициализированы члены класса, если в списке инициализации конструктора порядок их инициализации другой, чем в объявлении?
Ответ: Всегда первым инициализируется тот член, который первым объявлен в классе, независимо от порядка в списке инициализации конструктора. Это может привести к ошибкам при взаимозависимости членов класса.
История
В сложном классе при инициализации ссылки на член класса другой член был не проинициализирован. Оказалось, что порядок в списке инициализации не играет роли, и возникло использование неинициализированной памяти. ПО падало только при определенных компиляторах и настройках.
История
При добавлении нового члена в середину класса без корректировки порядка инициализации зависимых членов возникла ошибка, обнаруженная только при static code analysis. Переменная брала невалидное значение из-за старого порядка объявления.
История
Новая версия библиотеки меняла исходный код класса и поменяла порядок членов, не поменяв конструктор. В результате Values в приложении работали с невалидными данными: инженер долго не мог понять причину, пока не увидел warning компилятора о порядке инициализации.