4

以下内容有效吗?C++初始化列表和内存分配

class myClass 
{ 
    private: 
    ... 
    int m_nDataLength; 
    boost::shared_array<int> m_pData; 
    ... 

    public: 
    myClass(): ..., m_nDataLength(10), m_pData(new int[m_nDataLength]), ... 
    { 
    } 
} 

我是否正确地假设初始化会按照我在ctor中给出的顺序发生?如果没有,如果m_nDataLength的初始化发生在m_pData之后会发生什么?

+2

见http://stackoverflow.com/questions/1242830/constructor-initialization-list-evaluation-order。 – 2009-10-08 12:37:19

+0

我没有注意到这个,我的问题似乎是这个问题的重复。感谢您通知Luc。 – legends2k 2009-10-08 12:51:17

回答

10

虽然在你的榜样初始化你想要的顺序确实发生了,这是不是你认为的原因:初始化发生在数据成员声明类定义的顺序。这样做的原因是析构函数必须以向后顺序销毁成员,无论使用哪个构造函数创建对象。为此,必须使用定义建造顺序的独立于构造函数的方式。

这意味着,如果代替

class myClass 
{ 
    private: 
    ... 
    int m_nDataLength; 
    boost::shared_array<int> m_pData; 

有人会更改您的代码

class myClass 
{ 
    private: 
    ... 
    boost::shared_array<int> m_pData; 
    int m_nDataLength; 

那么代码将有一个错误。

我的建议是:

  • 写你的构造函数,以便initialiszati​​on顺序并不重要。
  • 如果你不能做到这一点(注意:在过去的十年中,发生这种事的次数少于5次),在声明数据成员的时候要明确这一点。

像这样的东西应该做的:

class myClass 
{ 
    private: 
    ... 
    int m_nDataLength;     // Note: Declaration order 
    boost::shared_array<int> m_pData; //  matters here! 
+0

哇,谢谢你在这里的所有答案。它已经修复了一个烦人的问题,并且让我大开眼界:) 但是我投这个是因为它的细节。 – legends2k 2009-10-08 12:48:37

9

初始化将被顺序初始化类领域的,因此:如果你改变

private: 
    ... 
    int m_nDataLength; 
    boost::shared_array<int> m_pData; 

private: 
    ... 
    boost::shared_array<int> m_pData; 
    int m_nDataLength; 

它不会工作。在构造函数中,该命令不适用。

5

不,类成员的初始化按照成员出现在类定义中的顺序进行。如果成员出现在初始化程序列表中,那么它将控制用于初始化该成员的表达式(即使它使用尚未初始化的成员),但它在初始化程序列表中出现的位置不会影响其初始化时间。