クラスに関して②:コンストラクタとデストラクタ
クラスの特殊なメンバ関数としてコンストラクタとデストラクタがある。
コンストラクタ
クラスをインスタンス化するときに自動的に呼ばれる。先の例ではコンストラクタの記述をしていないが、その場合デフォルトコンストラクタが呼ばれる。コンストラクタは、
- コンストラクタの名前はクラス名と同じ
- 戻り値はなし
例えば、以下のようにコンストラクタを定義することができる。この例ではインスタンスしたときにm_height=-1で初期化する。
man.h
CMan(); // publicで
man.cpp
CMan::CMan() : m_height(-1){ cout << "CManオブジェクト生成" << endl; }
デストラクタ
インスタンスが解放されるときに自動的に呼ばれる。こちらも記述しないとデフォルトデストラクタが呼ばれる。
- コンストラクタの名前は~+クラス名
- 戻り値はなし
man.h
~CMan(); // publicで
man.cpp
CMan::~CMan(){
cout << "CManオブジェクト破棄" << endl;
}
コンストラクタ・デストラクタが呼ばれるタイミング
を明確にするため、main.cppを以下のように書き換える。
int main(){ cout << "this is first line" << endl; CMan suzuki; cout << "instanciated" << endl; suzuki.set_age(40); cout << "age of suzuki is " << suzuki.get_age() << endl; cout << "height of suzuki is " << suzuki.get_height() << endl; // cout << "(backdoor)age of suzuki is " << suzuki.m_age << endl; CMan ueda; ueda.set_age(50); cout << "age of ueda is " << ueda.get_age() << endl; cout << "this is last line" << endl; return 0; }
実行結果は、
$ ./a.out this is first line CManオブジェクト生成 instanciated age of suzuki is 40 height of suzuki is -1 CManオブジェクト生成 age of ueda is 50 this is last line CManオブジェクト破棄 CManオブジェクト破棄
ということで、CMan Suzuki;の直後にコンストラクタが呼ばれる。デストラクタはreturn 0;の直前。
コンストラクタ・デストラクタ呼び出しタイミングの制御
main.cppを以下のように変更する。ポインタのため、メンバ関数の呼び出しは.から->に変更している。
int main(){ cout << "this is first line" << endl; //CMan suzuki; CMan* suzuki; suzuki = new CMan(); suzuki->set_age(40); cout << "age of suzuki is " << suzuki->get_age() << endl; cout << "height of suzuki is " << suzuki->get_height() << endl; // cout << "(backdoor)age of suzuki is " << suzuki.m_age << endl; delete suzuki; //CMan ueda; CMan* ueda; ueda = new CMan(); ueda->set_age(50); cout << "age of ueda is " << ueda->get_age() << endl; delete ueda; cout << "this is last line" << endl; return 0; }
実行結果は以下。newしたところでコンストラクタが呼ばれ、delしたところでデストラクタが呼び出される。
$ ./a.out this is first line CManオブジェクト生成 age of suzuki is 40 height of suzuki is -1 CManオブジェクト破棄 CManオブジェクト生成 age of ueda is 50 CManオブジェクト破棄 this is last line