오 C ++ 전문가, 당신의 지혜를 구합니다. 나에게 표준을 말하고 C ++가 다음 프로그램을 보장하는지 알려주십시오.
#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::~
즉, 멤버는 선언 순서에 따라 초기화되고 역순으로 소멸되는 것이 보장됩니까?
답변
즉, 멤버는 선언 순서에 따라 초기화되고 역순으로 소멸되는 것이 보장됩니까?
둘 다 예. 12.6.2 참조
6 초기화는 다음 순서로 진행됩니다.
첫째, 아래에서 설명하는 가장 많이 파생 된 클래스의 생성자에 대해서만 가상 기본 클래스는 기본 클래스의 방향성 비순환 그래프의 깊이 우선 왼쪽에서 오른쪽 순회에 나타나는 순서대로 초기화됩니다. -to-right”는 파생 된 클래스 base-specifier-list에서 기본 클래스 이름이 나타나는 순서입니다.
그런 다음 직접 기본 클래스는 기본 지정자 목록에 표시되는 선언 순서대로 초기화됩니다 (mem-initializer의 순서에 관계없이).
그런 다음 비 정적 데이터 멤버는 클래스 정의에서 선언 된 순서대로 초기화됩니다 (다시 mem-initializer의 순서에 관계없이).
마지막으로 생성자 본문의 복합 문이 실행됩니다. [참고 : 선언 순서는 기본 및 멤버 하위 개체가 초기화의 역순으로 삭제되도록해야합니다. —end note]
답변
예, 그렇습니다 (비 정적 멤버입니다). 초기화 (구성)에 대해서는 12.6.2 / 5를 참조하고 파괴에 대해서는 12.4 / 6을 참조하십시오.
답변
예, 표준은 객체가 생성 된 역순으로 파괴되도록 보장합니다. 그 이유는 한 개체가 다른 개체를 사용할 수 있으므로 이에 의존하기 때문입니다. 치다:
struct A { };
struct B {
A &a;
B(A& a) : a(a) { }
};
int main() {
A a;
B b(a);
}
경우 a
이전에 소멸했다 b
후 b
잘못된 멤버 참조를 개최한다. 생성 된 역순으로 개체를 파괴함으로써 올바른 파괴를 보장합니다.
답변
예, 그렇습니다. 소멸 순서는 멤버 변수의 경우 항상 생성 순서와 반대입니다.