Список инициализаторов для объектов с конструктором по умолчанию

Есть ли какая-то польза от помещения переменной члена класса в список инициализаторов, который не обязательно должен быть в списке инициализаторов? Пример:

class Foo
{
public:
Foo() {}
};

class Bar
{
public:
Bar() : _foo() {}

private:
Foo _foo;
};

В этом случае компилятор делает что-то особенное?

6

Решение

Список инициализаторов является предпочтительным способом инициализации членов в
конструктор. Это единственный возможный способ инициализации ссылки
члены и постоянные члены.

Кроме того, используя список инициализатора, вы уменьшаете
вероятность случайного использования переменной до того, как она была
инициализируется. Это часть большей философии никогда
определение переменной без ее инициализации.

7

Другие решения

В этом случае это не имеет значения.

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

Примечание. Если вы разместили их в неправильном порядке в списке интернализаторов, это обычно является просто предупреждением для большинства компиляторов (если вы не компилируете предупреждения как ошибки (что следует делать)).

Настоящая опасность связана с классами, которые имеют члены POD и конструктор, сгенерированный компилятором.

class NewFoo
{
int x;
int y;
};
// Version 1:
class Bar1
{
NewFoo  f;
};
// Version 2:
class Bar2
{
NewFoo  f;
public:
Bar2()  // f not in list.
{}
};
// Version 3:
class Bar3
{
NewFoo  f;
public:
Bar3()
: f()
{}
};

int main()
{
Bar1     b1a;           // x and y not  initialized.
Bar1     b1b = Bar1();  // x and y zero initialized.
Bar2     b2a;           // x and y not  initialized.
Bar2     b2b = Bar2();  // x and y not  initialized.
Bar3     b3a;           // x and y zero initialized.
Bar3     b3b = Bar3();  // x and y zero initialized.
}
9

Члены, которые не упомянуты в списке инициализатора используемого конструктора, инициализируются по умолчанию. За Foo это означает, что будет вызван конструктор по умолчанию.

Разница между Bar() : _foo() { } и не давая Bar явный конструктор по умолчанию вообще (или поговорка Bar() = default в том, что ваша версия не имеет тривиального конструктора по умолчанию. Таким образом, значения std::is_trivially_constructible<Bar>::value будет отличаться от того, если вы вообще не использовали конструктор, хотя в остальном поведение будет таким же.

6

Нет, в этом случае ничего другого не делается. Я не вижу никакой пользы от этого.

1
По вопросам рекламы [email protected]