使用成员初始化列表对成员进行初始化

4

这是我经常遇到的问题。下面的示例说明了它:

struct A {
    int m_SomeNumber;
};

struct B {
    B( A & RequiredObject );
private:
    A & m_RequiredObject;
};

struct C {
    C( );
private:
    A m_ObjectA;
    B m_ObjectB;
};
< p > C 的构造函数实现大致如下:

C::C( )
 : B( m_ObjectA )
{ }

由于初始化顺序未定义,当调用m_ObjectB的构造函数时,m_ObjectA可能未被初始化,导致未定义的行为。 一种强制特定初始化顺序的方法是使成员成为指针,并在构造函数体中初始化它们,从而强制正确顺序,但这种做法有很多不好之处。 是否有任何方法可以使用构造函数的初始化列表来强制特定的初始化顺序? 如果没有,请问你有什么其他建议来处理这个问题。
1个回答

12

由于初始化顺序未定义

相反,它是明确定义的。初始化顺序等同于在类中声明成员变量的顺序(而不管实际的初始化列表顺序!因此,让初始化列表顺序与声明顺序匹配是个好主意,以避免出现令人讨厌的意外情况)。


1
我想补充一下,这种方法非常脆弱,因为你对顺序的依赖可能不明显。所以至少我会在m_objectB的定义中添加一个注释,说明“必须在m_objectA之后定义”。 - peterchen
3
我会添加相应的编译器选项来警告您。在g++中,它是“-Wreorder”,以强制用户提供的初始化列表顺序与成员属性定义的顺序匹配。 - David Rodríguez - dribeas
@David - 非常有用。有人知道微软编译器是否有类似的东西吗? - Manuel
这种情况是否也适用于销毁顺序(我的直觉是相反的)? - Björn Pollex
@Space_C0wb0y:是的,完全正确。销毁发生在精确构建的相反顺序中,这也是明确定义的。 - Konrad Rudolph
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接