Порядок вызовов конструктора элементов и деструктора
О, гуру С++, я ищу твою мудрость. Поговорите со стандартным мне и сообщите моему, если С++ гарантирует, что следующая программа:
#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
Да и да. Порядок разрушения всегда противоположный порядку построения, для переменных-членов.