Является ли это поведение корректным?
class Foo
{
int A, B;
public:
Foo(int Bar): B(Bar), A(B + 123)
{
}
};
int main()
{
Foo MyFoo(0);
return 0;
}
Является ли это поведение корректным?
class Foo
{
int A, B;
public:
Foo(int Bar): B(Bar), A(B + 123)
{
}
};
int main()
{
Foo MyFoo(0);
return 0;
}
Нет, это undefined. A
будет инициализирован первым (сначала в определении класса), и он использует неинициализированный B
.
Члены класса инициализируются в том порядке, в котором они отображаются в определении класса, независимо от их порядка в списке инициализации. Действительно, неверная практика не соответствует порядку определения членства с порядком списка инициализации.
Если ваш экземпляр Foo
имел статическую продолжительность, как в Foo f(0); int main(){}
, поведение корректно определено. Объекты со статической продолжительностью инициализируются нулями перед любой другой инициализацией; в этом случае A
и B
будут равны 0 при запуске конструктора. Однако после этого поведение будет одинаковым: сначала A
, затем B
, давая A
значение 123 и B
значение Bar
(все еще некрасивое).
Нет, порядок инициализации определяется порядком объявления в самом классе.
Из стандарта С++ 12.6.2 [class.base.init] p5
:
Инициализация должна выполняться в следующем порядке:
- Во-первых, и только для конструктора самого производного класса, как описано ниже, виртуальные базовые классы должны быть инициализированы в том порядке, в каком они появляются на первом пересечении слева направо, направленном ациклическим графом базовых классов, где "слева направо" - это порядок появления имен базового класса в базе-спецификаторе производного класса.
- Затем прямые базовые классы должны быть инициализированы в порядке объявления, как они появляются в списке-спецификаторе-базовом (независимо от порядка mem-инициализаторов).
. Затем нестатические члены данных должны быть инициализированы в том порядке, в котором они были объявлены в определении класса (опять же, независимо от порядка mem-инициализаторов).
- Наконец, выполняется тело конструктора.
[Примечание: заказ декларации уполномочен гарантировать, что субобъекты базы и члена будут уничтожены в обратном порядке инициализации. ]
Инициализация выполняется в порядке появления в объявлении, а не в порядке, который вы пишете в конструкторе.
Посмотрите на этот вопрос, он несколько схож: Инициализационный список * аргумент * порядок оценки