С++: где инициализировать переменные в конструкторе
Возможный дубликат:
Списки инициализации С++
Каковы плюсы и минусы инициализации переменных в опции 1 по сравнению с опцией 2?
class MyClass
{
public:
MyClass( float f, char a );
private:
float mFloat;
char mCharacter;
bool mBoolean;
int mInteger;
};
MyClass::MyClass( float f, char a ) : mFloat( f ), mBoolean( true ) // option 1.
{
// option 2
mCharacter = a;
mInteger = 0;
}
Изменить:
Почему вариант 2 настолько распространен?
Ответы
Ответ 1
Короче говоря, всегда предпочитайте списки инициализации, когда это возможно. 2 причины:
-
Если вы не укажете переменную в списке инициализации класса, конструктор по умолчанию инициализирует ее, прежде чем вводить тело созданного вами конструктора. Это означает, что опция 2 приведет к тому, что каждая переменная будет записана дважды, один раз для инициализации по умолчанию и один раз для назначения в теле конструктора.
-
Также, как упоминалось mwigdahl и avada в других ответах, константные члены и ссылочные члены могут инициализировать только в списке инициализации.
Также обратите внимание, что переменные всегда инициализируются в том порядке, в котором они объявлены в объявлении класса, а не в том порядке, в котором они перечислены в списке инициализации (при правильных предупреждениях включенный компилятор предупредит вас, если список выписан из строя). Подобным же образом деструкторы будут вызывать деструкторы участников в обратном порядке, от первого до последнего в объявлении класса после выполнения кода в деструкторе класса.
Ответ 2
Хотя это не относится к этому конкретному примеру, Вариант 1 позволяет инициализировать переменные-члены ссылочного типа (или тип const
, как указано ниже). Вариант 2 - нет. В общем, вариант 1 - более мощный подход.
Ответ 3
См. Должны ли мои конструкторы использовать "списки инициализации" или "назначение" ?
Вкратце: в вашем конкретном случае это ничего не меняет. Но:
- для членов класса/структуры с конструкторами, может быть более эффективным использование опции 1.
- только опция 1 позволяет инициализировать ссылочные элементы.
- только опция 1 позволяет инициализировать члены const
- только опция 1 позволяет инициализировать базовые классы, используя их конструктор
- только опция 2 позволяет инициализировать массив или структуры, у которых нет конструктора.
Мое предположение о том, почему вариант 2 более распространен, заключается в том, что вариант 1 не является хорошо известным, и его преимущества отсутствуют. Синтаксис второй версии более естественен для нового программиста на С++.
Ответ 4
Вариант 1 позволяет использовать место, указанное точно для явно инициализации переменных-членов.
Ответ 5
Есть много других причин. Вы всегда должны инициализировать все переменные-члены в списке инициализации, если это возможно.
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6
Ответ 6
Вариант 1 позволяет инициализировать членов const
. Это невозможно сделать с помощью опции 2 (поскольку они назначены, а не инициализированы).
Почему константные члены должны быть инициализированы в инициализаторе конструктора, а не в его теле?