コンストラクタとデストラクタ

Home > 2006-06 / CからC++へ > This Entry [com : 0][Tb : 0]

2006-06-03

C++とCとの最大の違いはクラスかもしれません。そのため、クラスに関しては詳しく書く必要があるのですが、「C++と組み込み環境」はあくまでもブログであって、C++の入門サイトではありませんので、きちんとした解説を望まれる方は入門書を読まれることをお勧めします*1

今回は、クラスへの導入として、コンストラクタとデストラクタの話題を取り上げてみたいと思います。説明を簡単にするために、Cと同様の構造体に、コンストラクタとデストラクタを追加することに限定して書いてみます。

それでは例として、バイナリファイルを管理する次のような構造体を考えてみましょう。

struct binary_file
{
  char* name;
  FILE* stream;
};

構造体のメンバ(フィールド)を見れば、どんなデータ構造か大体想像が付くと思いますが、nameはファイル名を、streamはファイル記述子へのポインタを格納するためのものです。この構造体を使うには、オブジェクトを宣言した後、各メンバの初期化が必要になります。

struct binary_file bfile;
bfile.name = (char*)malloc(FILENAME_MAX);
strcpy(bfile.name, "sample.bin");
bfile.stream = fopen(bfile.name, "rb");

そして、使い終わった後で、

fclose(bfile.stream);
free(bfile.name);

のように、後始末をしなければなりません。これは、非常に面倒な上に可読性も低く、また、間違いを犯す危険性がかなり高いと思います。そこで、コンストラクタやデストラクタの出番となります。上の例を、コンストラクタとデストラクタを使って書き換えてみましょう。

struct binary_file
{
  char* name;
  FILE* stream;
  binary_file(const char* filename)
    : name((char*)malloc(FILENAME_MAX))
  {
    strcpy(name, filename);
    stream = fopen(name, "rb");
  }
  ~binary_file()
  {
    fclose(stream);
    free(name);
  }
};

構造体の中に、binary_fileという名前の関数と、~binary_fileという名前の関数の定義を書きました。前者がコンストラクタで、binary_file構造体のオブジェクトを宣言したときに呼び出されます。後者がデストラクタで、オブジェクトが生存期間を終えるときに呼び出されます。

それでは、この構造体の使い方を見てみましょう。

{
  struct binary_file bfile("sample.bin");
  // 何らかの処理
  // スコープから抜けるので、ここでデストラクタが呼び出される
}

このように、非常にすっきりとした記述になります。また、面倒な記述がなくなったことで、間違いを犯す可能性がほとんどなくなりました。

ところで、上の例では、bfileの宣言時に"sample1.bin"という引数を渡していますが、もしこの引数を渡さなければどうなるのでしょうか?実は、引数を渡さなければコンパイルエラーになります。

引数なしの宣言も行いたいのであれば、引数なしのコンストラクタ(デフォルトコンストラクタ)を多重定義するか、上の例で書いたコンストラクタで、filename = NULLのように省略時実引数を設定する必要があります。

コンストラクタとデストラクタについては、まだまだ書くべきことがあるのですが、長くなるので、今回はこの辺にしておきます。


*1 最近は入門書を読むこともなくなったので、お勧めの書籍とかもあまりないのですが、私がC++を学んだときは、「CプログラマのためのC++入門」でした。標準化以前に書かれた本ですので、今となってはやや古いのですが、それを考慮しても、非常によい本です。C++だけでなく、Cの理解も再確認させてくれます。

Comment

Post a Comment









管理者にだけ表示を許可

Trackback

http://cppemb.blog17.fc2.com/tb.php/68-3ee2e9b3

C++と組み込み環境 | Page Top▲

New >>
タグ名 == 型名
<< old
関数の多重定義
ブログ内検索
RSSフィード