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. –

+0

Я этого не заметил, мой вопрос кажется дублирующим. Спасибо, что уведомил Люка. – legends2k

ответ

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; 

тогда код будет иметь ошибку.

Мой совет:

  • Напишите свои конструкторами, так что порядок initialiszation не имеет значения.
  • Если вы не можете этого сделать (обратите внимание: для меня это произошло менее 5 раз за последнее десятилетие), сделайте это совершенно ясно в момент объявления членов данных.

Что-то вроде этого нужно сделать:

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

Вау, спасибо за все ответы здесь. Он исправил раздражающую проблему и стал для меня открытием :) Но я проголосовал за это за детали. – legends2k

9

инициализации будет инициализировать поля по порядку в классе, так: если вы меняете

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

как

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

это не будет работать. В конструкторе порядок не применяется.

5

Нет, инициализация для членов класса происходит в том порядке, в котором члены отображаются в определении класса. Если член появляется в списке инициализаторов, тогда он управляет выражением, используемым для инициализации этого элемента (даже если он использует элемент, который еще не был инициализирован), но там, где он отображается в списке инициализаций, не влияет на его инициализацию.