Порядок вызовов конструктора элементов и деструктора

О, гуру С++, я ищу твою мудрость. Поговорите со стандартным мне и сообщите моему, если С++ гарантирует, что следующая программа:

#include <iostream>
using namespace std;

struct A
{
    A() { cout << "A::A" << endl; }
    ~A() { cout << "A::~" << endl; }
};

struct B
{
    B() { cout << "B::B" << endl; }
    ~B() { cout << "B::~" << endl; }
};

struct C
{
    C() { cout << "C::C" << endl; }
    ~C() { cout << "C::~" << endl; }
};

struct Aggregate
{
    A a;
    B b;
    C c;
};

int main()
{
    Aggregate a;
    return 0;
}

всегда будет производить

A::A
B::B
C::C
C::~
B::~
A::~

Другими словами, члены гарантируются, что они будут инициализированы по порядку объявления и уничтожены в обратном порядке?

Ответ 1

Другими словами, члены гарантируются, что они будут инициализированы по порядку объявления и уничтожены в обратном порядке?

Да для обоих. См. 12.6.2

6 Инициализация должна выполняться в в следующем порядке:

  • Во-первых, и только для конструктор самого производного класс, как описано ниже, виртуальная база классы должны быть инициализированы в порядок они появляются на глубине слева направо направленный ациклический граф основания классы, где "слева направо" является порядок появления базового класса имена в производном классе базовый спецификатор-лист.

  • Затем, прямо базовые классы должны быть инициализированы в порядок декларации, как они появляются в список-спецификатор базы (независимо от порядок mem-инициализаторов).

  • Затем нестатические члены данных должны быть инициализированы в том порядке, в котором они были объявлено в определении класса (опять же, независимо от порядка MEM-инициализаторы).

  • Наконец, составная инструкция конструктора тело выполнено. [ Обратите внимание порядок подачи декларации обеспечить, чтобы базовые и членные подобъекты уничтожаются в обратном порядке инициализация. -end note]

Ответ 2

Да, они (нестатические члены, которые есть). См. 12.6.2/5 для инициализации (построения) и 12.4/6 для уничтожения.

Ответ 3

Да, стандартные гарантии объектов разрушаются в порядке, в котором они были созданы. Причина в том, что один объект может использовать другой, поэтому зависит от него. Рассмотрим:

struct A { };

struct B {
 A &a;
 B(A& a) : a(a) { }
};

int main() {
    A a;
    B b(a);
}

Если a нужно было разрушить до b, тогда b будет содержать недопустимую ссылку на элемент. Уничтожая объекты в обратном порядке, в которых они были созданы, мы гарантируем правильное уничтожение.

Ответ 4

Да и да. Порядок разрушения всегда противоположный порядку построения, для переменных-членов.