2017年12月10日
《その172》 派生クラスオブジェクトの初期化順序 & p.161演習4-2
派生クラスオブジェクトの初期化順序
派生クラスのコンストラクタが初期化作業を行うとき、その作業は次の順序で実行されます。
(1) 基底クラス部分オブジェクトの初期化
初期化作業は、基底クラスのコンストラクタに任せる。
(2) データメンバの初期化
クラス定義内で宣言された順に、データメンバが初期化される。
(3) コンストラクタ本体の実行
新版明解C++中級編 p.161 演習4-2
次のプログラムによって、派生クラスオブジェクトの初期化順序を確認することができる。
このプログラムを、デストラクタの起動順序を確認できるように書きかえたプログラムを作成せよ。
// ------------------------------------
#include <iostream>
using namespace std;
// クラス Derived の基底クラス
class Base {
int x;
public:
Base(int a = 0) : x(a) {
cout << "Base::x を" << x << "で初期化。\n";
}
};
// クラス Derived にメンバとして含まれるクラス
class Memb {
int x;
public:
Memb(int a = 0) : x(a) {
cout << "Memb::x を" << x << "で初期化。\n";
}
};
// 派生クラス Derived を生成
// (基底クラス Base から public派生)
class Derived : public Base {
int y;
Memb m1;
Memb m2;
void say() {
y = 0;
cout << "Derived::y を" << y << "で初期化。\n";
}
public:
Derived() { say(); }
Derived(int a, int b, int c)
: m2(a), m1(b), Base(c) {
say();
}
};
int main() {
Derived d1;
cout << '\n';
Derived d2(1, 2, 3);
}
// *** 実行結果 ****************
// * Base::x を0で初期化。 *
// * Memb::x を0で初期化。 *
// * Memb::x を0で初期化。 *
// * Derived::y を0で初期化。 *
// * *
// * Base::x を3で初期化。 *
// * Memb::x を2で初期化。 *
// * Memb::x を1で初期化。 *
// * Derived::y を0で初期化。 *
// *****************************
// ------------
◆以下が解答のプログラムと、その実行結果です。
// p161_演習4-2
#include <iostream>
using namespace std;
// クラス Derived の基底クラス
class Base {
int x;
public:
Base(int a = 0) : x(a) {
cout << "Base::x を" << x << "で初期化。\n";
}
~Base() { cout << "デストラクタ ~Base, "
<< "x = " << x << '\n';
}
};
// クラス Derived にメンバとして含まれるクラス
class Memb {
int x;
public:
Memb(int a = 0) : x(a) {
cout << "Memb::x を" << x << "で初期化。\n";
}
~Memb() { cout << "デストラクタ ~Memb, "
<< "x = " << x << '\n'; }
};
// 派生クラス Derived を生成
// (基底クラス Base から public派生)
class Derived : public Base {
int y;
Memb m1;
Memb m2;
void say() {
y = 0;
cout << "Derived::y を" << y << "で初期化。\n";
}
public:
Derived() { say(); }
Derived(int a, int b, int c)
: m2(a), m1(b), Base(c) {
say();
}
~Derived() { cout << "\nデストラクタ ~Derived, "
<< "y = " << y << '\n';
}
};
int main() {
Derived d1;
cout << '\n';
Derived d2(1, 2, 3);
}
この実行結果から、デストラクタの起動順序は、コンストラクタの初期化作業のときとは逆の順序であることが確認できます。
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7075621
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック