在C++中,类成员的初始化顺序始终是按照它们在类体内声明的顺序进行的,而不是按照它们在构造函数初始化列表中的顺序。
示例:
struct Foo { int a; int b; Foo() : b(2), a(b) {} };
在这个示例中,首先初始化a,其值是未定义的变量b,因为初始化a发生在初始化b之前,无论在初始化列表中的顺序如何。因此,a不等于2。
正确的方法是:在初始化时仅引用已在上方声明的成员或使用常量。
如果构造函数初始化列表中成员的初始化顺序与声明的顺序不同,成员将以什么顺序初始化?
答案: 始终首先初始化在类中首先声明的成员,无论构造函数初始化列表中的顺序如何。这可能导致成员之间相互依赖时出现错误。
故事
在一个复杂的类中,在初始化对另一个类成员的引用时,某个成员尚未初始化。结果发现,初始化列表中的顺序并不重要,导致使用未初始化的内存。这个问题仅在某些编译器和设置下发生。
故事
当在类中间添加新成员而未调整相关成员的初始化顺序时,出现了一个错误,仅在静态代码分析中发现。由于旧的声明顺序,变量获取了无效的值。
故事
库的新版本更改了类的源代码并更改了成员的顺序,但构造函数未更改。结果,应用程序中的值处理了无效数据:工程师很长时间都无法理解原因,直到看到编译器关于初始化顺序的警告。