ねむみ高まる

文章力がないので、文章を書く練習をしています。

【C++】クラスのメンバ変数のコンストラクタは宣言順に呼ばれ、デストラクタはその逆順に呼ばれる

クラスのメンバ変数の知識があやふやだったので、下のようなソースコードを書いて実験してみました。

aaa.cpp

#include <iostream>

using namespace std;

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

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

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

class AAA {
public:
    AAA()
    : a()
    , c() // cとbの初期化子リストの順番をあえて逆にしてみる
    , b()
    {
        cout << "AAA::AAA()" << endl; 
    }
    ~AAA() {
       cout << "AAA::~AAA()" << endl; 
    }
private:
    A a;
    B b;
    C c;
};

int main() {
    AAA aaa;
    return 0;
}

実行結果

A::A()
B::B()
C::C()
AAA::AAA()
AAA::~AAA()
C::~C()
B::~B()
A::~A()

というわけで、メンバ変数の宣言順にコンストラクタは呼ばれ、その逆順でデストラクタが呼ばれました。 なんと、初期化子リストの並びは関係ありません。。。かなり間違えやすいと思います。

ちなみにコンパイル時に clang++ -Wall aaa.cppのように -Wallを付けると、 下のようにwarningがちゃんと出ました。付けてないと出ませんでした。

aaa.cpp:39:7: warning: field 'c' will be initialized after field 'b' [-Wreorder]
    , c() // cとbの初期化子リストの順番をあえて逆にしてみる