Подтвердить что ты не робот

Список инициализации элемента С++

Пожалуйста, объясните, как использовать списки инициализации членов. У меня есть класс, объявленный в файле .h и .cpp, например:

class Example
{
private:
    int m_top;
    const int m_size;
    ...
public:
    Example ( int size, int grow_by = 1 ) : m_size(5), m_top(-1);
    ...
    ~Example();
};

Я инициализирую m_size при создании объекта из-за const. Как написать конструктор? Должен ли я повторять : m_size(5), m_top(-1), или я могу пропустить этот шаг?

Example::Example( int size, int grow_by)
{
... some code here
}

или

Example::Example( int size, int grow_by) : m_size(5), m_top(-1)
{
... some code here
}
4b9b3361

Ответ 1

Это список инициализации:

Example::Example( int size, int grow_by) : m_size(5), m_top(-1)
{
... some code here
}

и это нужно делать только в файле cpp.

Вы не получаете сообщение об ошибке, когда делаете это, как в заголовке в вашем примере?

Ответ 2

Просто чтобы прояснить то, что появилось в некоторых других ответах...

Не требуется, чтобы список инициализации находился в файле источника (.cpp) или заголовка (.h). На самом деле компилятор не различает файлы двух типов. Важное различие между конструктором declaration и его определением. Список инициализации идет с определением, а не с объявлением.
Обычно декларация находится в файле заголовка, и определение находится в исходном файле, однако это не является обязательным для языка (т.е. Он будет компилировать). Необязательно предоставлять определения конструктора inline в объявлении класса, когда конструктор пуст или короток. В этом случае список инициализации войдет в объявление класса, которое, вероятно, будет в файле заголовка.

MyClass.h

class MyClass
{
public:
    MyClass(int value) : m_value(value)
    {}
private:
    int m_value;
};

Ответ 3

Список инициализаторов элементов должен быть частью определения в исходном файле.
Запишите это в файл .cpp:

Example ( int size, int grow_by) : m_size(5), m_top(-1)
{

}

Файл заголовка должен содержать только:

Example ( int size, int grow_by = 1 );

Заголовочный файл объявляет только конструктор, список инициализаторов членов не является частью объявления.

Ответ 4

Добавляя к другим ответам, самое важное, что нужно помнить о списке инициализации, состоит в том, что the order of initialization is decided in the order in which the data members are declared, not the the order in which you have initialized the data members using initialization list

Рассмотрим пример (ваш):


class Example
{
private:
    int m_top;
    const int m_size;
    ...
public:
    Example ( int size, int grow_by = 1 ) : m_size(5), m_top(-1){}

                   /* Though size is initialized with a value first
                       But it is m_top variable that is assigned value -1
                       before m_size is assigned value 5 */
    ...
    ~Example(){}
};

Если кто-то не знает об этом, это может вызвать очень серьезные последствия.

Ответ 5

В С++ 11 вы можете использовать инициализацию нестатических элементов данных. Это особенно полезно, если у вас есть несколько конструкторов, которым требуется общее значение для переменной-члена.

class Example
{
private:
    int m_top = -1;
    const int m_size = 5;
    ...
public:
    Example ( int size, int grow_by = 1 );
    ...
    ~Example();
};

...

Example::Example( int size, int grow_by )
{
    ... some code here
}

Вы можете переопределить значение в конструкторе, если вам нужно.

Ответ 6

Вы не можете инициализировать список как в заголовке, так и в cpp. В списке должно быть указано, когда когда-либо файл определяет ваш конструктор. Также вы должны включить тело для конструктора, даже если оно пустое.

На стороне примечания вы должны указывать только аргументы по умолчанию в прототипе функции не в определении.