Является ли это поведение четко определенным?
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;
}
Нет, это не определено. A
будет инициализирован первым (он первый в определении класса), и он использует неинициализированный B
.
Члены класса инициализируются в том порядке, в котором они указаны в определении класса, независимо от их порядка в списке инициализации. Действительно, несоответствие порядка определения членов порядку списка инициализации является плохой практикой.
Если ваш экземпляр Foo
имел статическую продолжительность, как в Foo f(0); int main(){}
, поведение четко определено. Объекты со статической продолжительностью инициализируются нулями до того, как произойдет любая другая инициализация; в этом случае A
и B
будут равны 0 при запуске конструктора. Однако после этого поведение такое же: сначала A
, затем B
, присваивая A
значение 123, а B
значение Bar
(все еще уродливо).
Foo(int Bar): A(Bar + 123), B(Bar) { }
.
- person Kerrek SB; 09.06.2011
-Wextra
.
- person Maxpm; 09.06.2011
-Wall
было бы достаточно, хотя я согласен, что было бы здорово, если бы он был активен по умолчанию.
- person Matthieu M.; 10.06.2011
Нет, порядок инициализации определяется порядком объявления в самом классе.
Из стандарта С++ 12.6.2 [class.base.init] p5
:
Инициализация должна выполняться в следующем порядке:
— Сначала и только для конструктора наиболее производного класса, как описано ниже, виртуальные базовые классы должны быть инициализированы в том порядке, в котором они появляются при обходе в глубину слева направо. ориентированного ациклического графа базовых классов, где «слева направо» — порядок появления имен базовых классов в списке-спецификаторов-базовых-производных классов.
— Затем в порядок объявления в том порядке, в котором они появляются в списке спецификаторов базы (независимо от порядка инициализаторов памяти).
— Затем нестатические элементы данных должны быть инициализированы в том порядке, в котором они были объявлены в определении класса ( снова независимо от порядка мем-инициализаторов).
— Наконец, выполняется тело конструктора.
[Примечание: порядок объявления гарантирует, что базовые подобъекты и подобъекты-члены будут уничтожены в порядке, обратном инициализации. ]
Инициализация выполняется в порядке появления в объявлении, а не в том порядке, в котором вы пишете его в конструкторе.
Посмотрите на этот вопрос, он чем-то похож: Список инициализаторов *аргумент* порядок оценки