Порядок списка инициализации участника

После многократного упрощения кода я обнаружил, что причиной является следующая проблема.

class B {
public:
    B(const int x)
              :_x(x) {}
    const int _x;
};

class C {
public:
    C(const B& b) 
        : _b(b), _b2(_b._x) {}
    B _b2;       // line 1
    const B& _b; // line 2
};

int main() {
    B b(1);
    C c(b);
}

Предупреждение (лязг 8.0.0)

test16.cpp:11:22: warning: reference '_b' is not yet bound to a value when used here [-Wuninitialized]
        : _b(b), _b2(_b._x) {}
                     ^
1 warning generated.

g ++ - 6 компилирует программу. Запуск программы вызывает ошибку сегментации.

Соответствует ли инициализация членов класса порядку списка инициализации членов (: _b(b), _b2(_b._x)) или порядок членов в классе (например, B _b2; const B& _b;)

2 ответа

Решение

Инициализация переменных-членов происходит в том порядке, в котором они объявлены в классе.

http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines

а также:

http://en.cppreference.com/w/cpp/language/initializer_list

3) Затем не статические члены данных инициализируются в порядке объявления в определении класса.

Порядок, указанный в списке инициализаторов членов, не имеет значения, нестатические члены инициализируются в порядке объявления в определении класса.

Порядок инициализаторов элементов в списке не имеет значения: фактический порядок инициализации следующий:

3) Затем не статические члены данных инициализируются в порядке объявления в определении класса.

Это означает _b2 всегда будет инициализирован до _b; и когда _b используется для инициализации _b2 это все еще не инициализировано.

Кстати: аналогичное правило применяется для инициализации прямых базовых классов.

2) Затем прямые базовые классы инициализируются в порядке слева направо, как они появляются в списке базовых спецификаторов этого класса.

Другие вопросы по тегам