第二回-03 : コンストラクタとデストラクタ

本ページではコンストラクタとデストラクタを持つ stack クラスについて解説する。

stack クラスのオブジェクトを main 関数で「stack s1;」などと宣言して呼び出す際、
必ず「s1.init();」命令による初期化が必要だった (理由は考えてみよ)。

一般に、このような必要な初期化をうっかり記述し忘れると、重大なエラーを引き起こすことが多い。
そのため、記述忘れをしても困らないよう、初期化処理がオブジェクト宣言時に自動的に呼び出されると便利である。
そのような仕組みが「コンストラクタ」である。
逆に、オブジェクトを破棄するときに自動的に呼び出される処理が「デストラクタ」である。

以下、具体例をもとに解説しよう。


ソースコード

ソースコードは以下のようになる。
見やすさを考慮して「クラス宣言部」、「クラス実現部」、「クラス利用部」 の先頭を赤字で表示した。
また、 「(※1)」などと書かれている部分は後に解説で参照される。

//クラス宣言部
#include <iostream>
using namespace std;

#define SIZE 10

// 文字を保存するstackクラスを宣言する
class stack {
  char stck[SIZE]; // スタック領域を確保する
  int tos; // スタック先頭の索引
public:
  stack();  // コンストラクタ (※1)
  ~stack(); // デストラクタ (※2)

  void init(); // スタックを初期化する
  void push(char ch); // スタックに文字をプッシュする
  char pop(); // スタックから文字をポップする
};
//クラス実現部
// コンストラクタ
stack::stack()
{
  cout << "スタックを生成する\n";
  tos = 0;
}
// デストラクタ
stack::~stack()
{
  cout << "スタックを破棄する\n";
}
// スタックを初期化する
void stack::init()
{
  tos = 0;
}
// 文字をプッシュする
void stack::push(char ch)
{
  if(tos==SIZE) {
    cout << "スタックは一杯です";
    return;
  }
  stck[tos] = ch;
  tos++;
}
// 文字をポップする
char stack::pop()
{
  if(tos==0) {
    cout << "スタックは空です";
    return 0; // スタックが空の場合はヌルを返す
  }
  tos--;
  return stck[tos];
}
//クラス利用部
int main(){
  stack s1, s2;  // 2つのスタックを作成する  (※3)
  int i;

  s1.push('a');
  s2.push('x');
  s1.push('b');
  s2.push('y');
  s1.push('c');
  s2.push('z');

  for(i=0; i<3; i++) cout << "s1をポップする: " << s1.pop() << "\n";
  for(i=0; i<3; i++) cout << "s2をポップする: " << s2.pop() << "\n";

  return 0;   // (※4)
}



前ページの stack クラスからの変更点に注意してコンストラクタ/デストラクタつきの stack クラスの動作を確認してみよ。

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

クラス宣言部から以下のことがわかる。 また、プログラムを実行することで、以下のことがわかる。 どちらも、明示的に呼び出さなくても実行されることに注意。

なお、この例ではデストラクタを記述する必要は特にないが、デストラクタの呼び出されるタイミングを知ってもらうためにデストラクタを追加した。

←第二回-02: stack クラスの動作第二回-04:メモリとポインタ→

第二回演習用 web ページへ

クラスから入る C++ へ戻る