【C++入門】コンストラクタ・デストラクタの呼び出し順序をわかりやすく解説
このチュートリアルでは、C++におけるコンストラクタとデストラクタの呼び出し順序について、サンプルプログラムを通じて解説します。
コンストラクタ/デストラクタの「呼び出し順序」とは、クラスの継承関係において、基底クラスと派生クラスそれぞれのコンストラクタやデストラクタがどのような順番で実行されるかを示すパターンのことです。この挙動を正しく理解することは、C++のオブジェクト指向プログラミングにおいて非常に重要な基礎知識となります。
コンストラクタの呼び出し順序
C++では、派生クラスのオブジェクトを生成すると、まず基底クラスのコンストラクタが呼び出され、その後に派生クラスのコンストラクタが呼び出されます。つまり、「基底クラス → 派生クラス」の順で初期化処理が進みます。
サンプルコード
#include <iostream>
using namespace std;
// 親クラス(基底クラス)
class Parent {
public:
Parent() {
cout << "基底クラスのコンストラクタ" << endl;
}
};
// 子クラス(派生クラス)
class Child : public Parent {
public:
Child() {
cout << "派生クラスのコンストラクタ" << endl;
}
};
int main() {
Child obj;
return 0;
}実行結果
基底クラスのコンストラクタ 派生クラスのコンストラクタ
このように、Child型のオブジェクトを1つ生成しただけでも、先に親であるParentクラスのコンストラクタが実行されていることがわかります。これは、派生クラスが基底クラスの機能を受け継ぐため、基底クラス側を先に正しく初期化しておく必要があるからです。
デストラクタの呼び出し順序
一方、デストラクタはコンストラクタとは逆の順序で呼び出されます。オブジェクトが破棄される際には、まず派生クラスのデストラクタが実行され、その後に基底クラスのデストラクタが実行されます。
サンプルコード
#include <iostream>
using namespace std;
class Parent {
public:
Parent() {
cout << "基底クラスのコンストラクタ" << endl;
}
~Parent() {
cout << "基底クラスのデストラクタ" << endl;
}
};
class Child : public Parent {
public:
Child() {
cout << "派生クラスのコンストラクタ" << endl;
}
~Child() {
cout << "派生クラスのデストラクタ" << endl;
}
};
int main() {
Child obj;
return 0;
}実行結果
基底クラスのコンストラクタ 派生クラスのコンストラクタ 派生クラスのデストラクタ 基底クラスのデストラクタ
実行結果を見ると、生成時は「基底 → 派生」、破棄時は「派生 → 基底」と、完全に対称的な順序になっていることが確認できます。これは、後から構築された部分(派生クラス)を先に片付けることで、リソース管理の一貫性を保つためです。
まとめ
- コンストラクタ:基底クラス → 派生クラス の順に呼び出される
- デストラクタ:派生クラス → 基底クラス の順に呼び出される(コンストラクタの逆順)
継承を使ったクラス設計では、この順序を意識してメンバ変数の初期化やリソースの解放処理を実装することが大切です。特に、基底クラスのコンストラクタで取得したリソースを派生クラスで利用する場合などは、呼び出し順序を正しく理解しておくことで予期しないバグを防げます。
-
C++のローカルクラスとは?特徴・制約と実装例をわかりやすく解説
ローカルクラスとは C++において、関数の中で宣言されたクラスは「ローカルクラス」と呼ばれます。これは、そのクラスが定義された関数の内部でのみ有効であるためです。 まず、ローカルクラスの基本的な構造を見てみましょう。 #include<iostream> using namespace std; void func() { class LocalClass { }; } int main() { return 0; } 上記の例では、関数 func() の中で LocalClass が定義されています。このように関数の内部で宣言されたクラスが、ローカルクラス
-
PHPで子クラスから親クラスのコンストラクターを呼び出す方法
PHPでは、子クラスから親クラスのコンストラクターを呼び出す場面において、大きく分けて2つのケースが考えられます。それぞれのケースについて、具体例とともに解説します。ケース1:子クラスが独自のコンストラクターを定義している場合子クラスでコンストラクターが定義されている場合、親クラスのコンストラクターは自動的には実行されません。親クラスのコンストラクターを実行したい場合は、子クラスのコンストラクター内で parent::__construct() を明示的に呼び出す必要があります。コード例<?php class grandpa{ &n