成员按照它们在类定义中出现的顺序进行初始化(与初始化列表中的顺序无关)。因此,首先初始化m1,您可以使用它的值来初始化m2。
这段代码
class A
{
private:
M1Type m1;
const M2Type m2;
public:
A(int x) : m1(x), m2(m1){}
};
很好(除了缺少x 的类型)。不过,如果可能的话,我宁愿这样写:
class A
{
private:
M1Type m1;
const M2Type m2;
public:
A(int x) : m1(x), m2(x){}
};
因为现在正确性不取决于成员的顺序。重构时可能会发生变化。当初始化列表中的顺序不同时,编译器通常会发出警告,但您可以依赖正确的代码,而不是依赖警告,而不管成员的顺序如何。
请注意,编译器不一定会警告此代码(交换成员的顺序):
class A
{
private:
const M2Type m2;
M1Type m1;
public:
A(int x) : m2(m1),m1(x) {} // !! most likely UB !!
};
但如果M2Types 构造函数使用m1 的值,它具有未定义的行为,因为m1 未初始化使用。因此,当成员的初始化相互依赖时应该小心。