[c++] 멤버 생성자 및 소멸자 호출 순서

오 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이전에 소멸했다 bb잘못된 멤버 참조를 개최한다. 생성 된 역순으로 개체를 파괴함으로써 올바른 파괴를 보장합니다.


답변

예, 그렇습니다. 소멸 순서는 멤버 변수의 경우 항상 생성 순서와 반대입니다.


답변