クラスの定義とnewによるオブジェクトの生成,メンバ関数 |
使用ソースコードをダウンロードして参考にして下さい。
● デストラクタ
C++では,インスタンスのメモリ空間がdeleteの呼び出しやスコープの終了によって解放される直前に自動的に呼び出されるメンバ関数を定義しておくこと
ができます。これをデストラクタ(destructor)と呼びます。このデストラクタを適切に定義しておくことで,インスタンスの寿命が尽きる前に必要な事後処理を
行わせることが可能になります。
デストラクタは,クラスの型名の先頭に”~”を付けた名前を持つ,仮引数も返却値も無いメンバ関数として定義します(Fig. 2.12)。
コンストラクタと同様に返却値の型を指定してはいけません。もし,明示的にデストラクタを宣言・定義しない場合には,暗黙的な公開なデストラクタが
自動的に宣言・生成されます。この暗黙的に自動生成されるデストラクタの処理本体は空です。ですから,コンストラクタの項であげた
class T {
};
という例の場合には,実は自動的に公開のデフォルトコンストラクタとデストラクタが自動で追加され,実際には
class T {
public :
T() {}
~T() {}
};
という定義になるわけです。
デストラクタは,そのオブジェクトのライフタイムが終了する直前(そのオブジェクトの占めているメモリ領域が解放される直前)に自動的に呼ばれます。
つまり,
・
局所変数として宣言されたオブジェクトの場合は制御がそのスコープを出たときに自動的に呼ばれる。
・大域変数として宣言されたオブジェクトではプログラムの終了時に自動的に呼ばれまる。
・
newで動的に確保したオブジェクトの場合は,deleteでオブジェクトが破棄される直前に自動的に呼ばれる。
というわけです。このように,デストラクタはクラスにひとつだけ必ず存在し,オブジェクトのライフタイムが終わるときには,その唯一のデストラクタが起動
されるのです。もし,デストラクタが明示的に非公開として宣言・定義された場合にはエラーとなりますので,公開メンバとして定義しましょう。
デストラクタの使用例を以下に挙げます。
destruc.cpp
#include <iostream> using namespace std; enum gender { male, female }; class Person { public : int age; gender gen; void talk() { cout << "Hello! I am " << age << " years old." << endl; } Person( int age, gender gen ) { this->age = age; this->gen = gen; } ~Person() { if ( gen == male ) { cout << "(^o^) bye!" << endl; } if ( gen == female ) { cout << "(*^^*) bye!" << endl; } } }; int main() { Person * taro = new Person( 20, male ); Person * hanako = new Person( 18, female ); taro->talk(); hanako->talk(); delete hanako; delete taro; char c; cin >> c; return 0; }
ここで使用されている this は,自オブジェクトへのポインタ値を表す名前です。よく使うので覚えておきましょう。
また,C++のクラスは,C言語の構造体を文法的に拡張したものなので,
オブジェクトへのポインタ値 -> メンバ変数
オブジェクトへのポインタ値 -> メンバ関数(実引数 )
という形でポインタで指し示されたオブジェクトのメンバを利用できます。
ここまで変数のライフタイムにそって,様々な問題点をチェックしてきました。C言語にくらべて,C++がいかに安全で正しいプログラムを作りやすいようになって
いるかおわかりになっていただけたでしょう。