1. ホーム
  2. c++

[解決済み] メンバコンストラクタとデストラクタの呼び出しの順番

2022-06-12 21:29:31

質問

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 初期化は次の順序で行う。 次の順序で行う。

  • 最初に、そして のコンストラクタのみです。 クラスのコンストラクタに限り、仮想基底 クラスは の深さ優先順位で表示されます。 の左から右への深さ優先走査に現れる順序で初期化されなければならない。 の有向非循環グラフを深さ優先で左から右に走査したときに現れる順序で初期化されなければならない。 ここで、"left-to-right" は基底クラスの出現順序である。 ベースクラスが出現する順序 の名前の出現順である。 base-specifier-listにあるベースクラス名の出現順です。

  • では、直接 基底クラスは に現れるように宣言順に初期化されなければならない。 の宣言順に初期化される。 に現れるように宣言順に初期化されなければならない(mem-initializersの順序に関係なく)。

  • 次に、非静的データメンバは クラス定義で宣言された順序で初期化されなければならない。 で宣言された順に初期化されなければならない。 (の順序に関係なく)。 mem-initializersの順序に関係なく)。

  • 最後に コンストラクタの複合ステートメント のボディが実行されます。[注意: 宣言の順序は 宣言の順序は ベースオブジェクトとメンバサブオブジェクトが が初期化されたときと逆の順序で破壊されるようにするためです。 初期化とは逆の順序で破壊されるようにするためです。-注意の終わり ]。