C++のコンストラクターはいつ呼び出される?オブジェクトの種類別に解説
C++では、コンストラクターが呼び出されるタイミングはオブジェクトの種類によって異なります。オブジェクトには「グローバル」「ローカル(非静的)」「静的ローカル」「動的」の4種類があり、それぞれ呼び出しのタイミングが異なるため、正しく理解しておくことが重要です。本記事では、各ケースについてサンプルコードと実行結果をもとに詳しく解説します。
1. グローバルオブジェクトの場合:main関数の実行前に呼び出される
グローバルオブジェクトのコンストラクターは、main関数が実行される前に呼び出されます。プログラムの起動時にオブジェクトが初期化されるためです。
サンプルコード
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() {
cout << "Calling Constructor" << endl;
}
};
MyClass myObj; // グローバルオブジェクト
int main() {
cout << "Inside Main";
}
実行結果
Calling Constructor Inside Main
実行結果を見ると、main関数内の「Inside Main」よりも先に「Calling Constructor」が出力されています。これは、グローバルオブジェクトの生成がmain関数の実行より前に行われるためです。
2. ローカル(非静的)オブジェクトの場合:定義位置に実行が到達したとき
非静的なローカルオブジェクトの場合、コンストラクターは実行フローがオブジェクトの定義文に到達した時点で呼び出されます。
サンプルコード
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() {
cout << "Calling Constructor" << endl;
}
};
int main() {
cout << "Inside Main" << endl;
MyClass myObj; // ローカルオブジェクト
cout << "After creating object";
}
実行結果
Inside Main Calling Constructor After creating object
「Inside Main」の出力後、myObjが定義された行でコンストラクターが呼び出され、その後の処理が続いていることが確認できます。
3. 静的ローカルオブジェクトの場合:最初の1回だけ呼び出される
関数内でstatic指定されたローカルオブジェクトの場合、コンストラクターは初めてその定義文が実行されるときに一度だけ呼び出されます。同じ関数を何度呼び出しても、2回目以降にコンストラクターが実行されることはありません。
サンプルコード
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() {
cout << "Calling Constructor" << endl;
}
};
void func() {
static MyClass myObj; // 静的ローカルオブジェクト
}
int main() {
cout << "Inside Main" << endl;
func();
cout << "After creating object" << endl;
func();
cout << "After second time";
}
実行結果
Inside Main Calling Constructor After creating object After second time
func()を2回呼び出していますが、「Calling Constructor」は1回しか出力されていません。静的ローカルオブジェクトはプログラム全体で1つだけ存在し、最初の通過時にのみ初期化されるためです。
4. 動的オブジェクトの場合:new演算子で生成したとき
動的に確保するオブジェクトの場合、コンストラクターはnew演算子によってオブジェクトが生成されたときに呼び出されます。ポインター変数を宣言しただけでは、まだコンストラクターは呼び出されない点に注意してください。
サンプルコード
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() {
cout << "Calling Constructor" << endl;
}
};
int main() {
cout << "Inside Main" << endl;
MyClass *ptr;
cout << "Declaring pointer" << endl;
ptr = new MyClass;
cout << "After creating dynamic object";
}
実行結果
Inside Main Declaring pointer Calling Constructor After creating dynamic object
ポインター宣言の時点では何も起こらず、newでMyClassのインスタンスを生成した瞬間にコンストラクターが呼び出されていることがわかります。
まとめ:コンストラクターの呼び出しタイミング一覧
| オブジェクトの種類 | コンストラクターの呼び出しタイミング |
|---|---|
| グローバルオブジェクト | main関数の実行前 |
| ローカル(非静的)オブジェクト | 定義文に実行が到達したとき |
| 静的ローカルオブジェクト | 初めて定義文が実行されるとき(以降は呼ばれない) |
| 動的オブジェクト | new演算子で生成したとき |
このように、オブジェクトの生成方法や記述場所によって、コンストラクターの実行タイミングは大きく変わります。特に、静的ローカルオブジェクトの初期化が1回限りである点や、動的オブジェクトはnewの実行時まで生成されない点は、実務でも頻繁に関わる重要な挙動なので、しっかり押さえておきましょう。
-
C/C++からPythonオブジェクトを操作する方法(Cython埋め込みの実践ガイド)
C/C++からPythonオブジェクトを使うには?CやC++のプログラムからPythonオブジェクトを直接生成・操作したい場合、Cythonを利用するのが最も手軽な方法の一つです。ここでは、シンプルなPythonクラスをCythonでラップし、C言語側に組み込んで(埋め込んで)呼び出す例を紹介します。C++の場合も手順はほぼ同じで、コンパイル時に--cplusオプションを付けるだけで対応できます。ステップ1:Pythonクラスと公開関数を定義する(pycls.pyx)まず、ラップ対象となるPythonクラスと、C側から呼び出せるようにするためのcdef public関数を定義したファイル「py
-
Pythonオブジェクトがガベージコレクションの対象になるタイミングとは?参照カウントの仕組みを解説
Pythonオブジェクトはいつガベージコレクションの候補になるのか Pythonにおいて、オブジェクトや変数がガベージコレクション(GC)の候補になるのは、そのオブジェクトへの参照がすべて無効になった瞬間です。具体的には、以下のようなケースが該当します。 オブジェクトへのすべての参照がスコープ外に出たとき del x のように手動で参照を削除したとき 変数に別のオブジェクトを再代入し、元のオブジェクトへの参照が失われたとき 重要なのは、プログラム内のどこからもそのオブジェクトが参照されていない状態にならなければ、ガベージコレクションの対象にはならないという点です。一箇所でも参照が残っていれ