Подтвердить что ты не робот

Зависимости в списках инициализации

Является ли это поведение корректным?

class Foo
{
    int A, B;

    public:

    Foo(int Bar): B(Bar), A(B + 123)
    {
    }
};

int main()
{
    Foo MyFoo(0);
    return 0;
}
4b9b3361

Ответ 1

Нет, это undefined. A будет инициализирован первым (сначала в определении класса), и он использует неинициализированный B.

Члены класса инициализируются в том порядке, в котором они отображаются в определении класса, независимо от их порядка в списке инициализации. Действительно, неверная практика не соответствует порядку определения членства с порядком списка инициализации.

Если ваш экземпляр Foo имел статическую продолжительность, как в Foo f(0); int main(){}, поведение корректно определено. Объекты со статической продолжительностью инициализируются нулями перед любой другой инициализацией; в этом случае A и B будут равны 0 при запуске конструктора. Однако после этого поведение будет одинаковым: сначала A, затем B, давая A значение 123 и B значение Bar (все еще некрасивое).

Ответ 2

Нет, порядок инициализации определяется порядком объявления в самом классе.

Из стандарта С++ 12.6.2 [class.base.init] p5:

Инициализация должна выполняться в следующем порядке:
- Во-первых, и только для конструктора самого производного класса, как описано ниже, виртуальные базовые классы должны быть инициализированы в том порядке, в каком они появляются на первом пересечении слева направо, направленном ациклическим графом базовых классов, где "слева направо" - это порядок появления имен базового класса в базе-спецификаторе производного класса.
- Затем прямые базовые классы должны быть инициализированы в порядке объявления, как они появляются в списке-спецификаторе-базовом (независимо от порядка mem-инициализаторов).
. Затем нестатические члены данных должны быть инициализированы в том порядке, в котором они были объявлены в определении класса (опять же, независимо от порядка mem-инициализаторов).
- Наконец, выполняется тело конструктора.
[Примечание: заказ декларации уполномочен гарантировать, что субобъекты базы и члена будут уничтожены в обратном порядке инициализации. ]