Порядок списка инициализации участника
После многократного упрощения кода я обнаружил, что причиной является следующая проблема.
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) Затем прямые базовые классы инициализируются в порядке слева направо, как они появляются в списке базовых спецификаторов этого класса.