2013年8月6日火曜日

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

コンストラクタとは、オブジェクトを生成するときに必ず呼び出される関数です。
主な役割が、メンバ変数の初期化を行うことです。

以前取り上げたPeachBoxクラスでは、これまでEmpty()関数でモモの箱を空にして
(桃の数を0に初期化)してから、Add()関数で桃を追加していました。

    :
int main(void)
{
    PeachBox myPeachBox;    //オブジェクトを生成、すなわちmyPeachBoxがインスタンス化

    myPeachBox.Empty();    //初期化 桃の数を0にする
    myPeachBox.Add(12);    //桃を1ダース追加
            :
    return 0;
}

このようにEmpty()関数を先に呼べば安全なのですが、Empty()関数を呼ばずにAdd()関数を
呼び出すと、桃の数を表すメンバ変数m_totalが初期化されてない状態で値を加えることになります。
変数はキチンと宣言しただけでは、不定値が入っています。たまたま0かもしれませんし、そうではないかもしれません。これは予想のできない動作を招くおそれがあります。

コンストラクタの定義
コンストラクタは、オブジェクトの生成時に自動的に呼び出される特殊な関数です。
コンストラクタは、アクセス指定子をpublicにして記述します。privateにしたり、アクセス指定子を
省略するとコンパイルエラーになりますので注意してください。

class PeachBox{
public:
    PeachBox();    //コンストラクタの宣言です^^  必ずクラス名と同じ名前になります
        :
};

PeachBox::PeachBox()  //コンストラクタの処理を定義します
{
    m_total = 0;       //メンバ変数を初期化しています
}
    :
int main(void)
{
    PeachBox myPeachBox;   //ここでコンストラクタが呼び出される
            :
}

コンストラクタには戻り値がなく、型も指定しないことに注意してください。
このように、コンストラクタでメンバ変数の値を初期化することで、さきほどの様にメンバ変数が
不定値のまま使用することで、予期せぬ結果になるという事態を防ぐことができます。 

なお、コンストラクタは引数なしのもの、引数ありのもの、のように複数定義できます。
具体的な使い方は次回以降で見ていくこととします^^

もし、コンストラクタで行う処理が何もなければコンストラクタは記述しなくてもかまいません。
その場合でも、内部的には自動でコンストラクタを生成し呼び出しているのです(^^)v


次に、デストラクタについて見ていきます。
こちらは、オブジェクトが消滅する時に呼ばれる関数です。
主な役割は、プログラムの後始末を行うことです。

デストラクタもアクセス指定子はpublicにします。privateにしたりアクセス指定子を省略すると
コンパイルエラーになりますのでご注意を(^_^;)

class PeachBox {
public:
    PeachBox();
    ~PeachBox();    //デストラクタの宣言です。 クラス名と同じ名前で先頭に~(チルダ)が付きます。
        :
};

        :
PeachBox::~PeachBox()  //デストラクタの定義です。 ここではプログラム終了を表示しています。
{
    std::cout << "桃の化粧箱オブジェクトが終了します。" << std::endl;
}
        :
int main(void)
{
    PeachBox myPeachBox();

    myPeachBox.Add(12);
    std::cout << "化粧箱の中の桃の数は" << myPeachBox.GetTotal() << "個です。" << std::endl;

  return 0;
}         //オブジェクトの有効範囲はここまで

デストラクタはオブジェクトの有効範囲が終わった時に呼び出されます。
上記の場合は、return 0 でmain()関数が終了した後になります。

実行例
root# ./peach
化粧箱の中の桃の数は12個です。
桃の化粧箱オブジェクトが終了します。


便利なデストラクタの使い方
 プログラムの後始末ですので、メンバ関数内で動的にメモリを確保した場合に、デストラクタで
 解放するようにしておくと、メモリ解放漏れがなくなり安心です。

デストラクタの特徴
 コンストラクタ同様、デストラクタにも戻り値がなく、型も指定しません。
 また引数をもてず、クラスの中に一つだけしか定義できません。
  
 デストラクタも必要な処理が何もなければ、定義する必要はありません。
 その場合でも、内部的には自動でデストラクタを生成し、呼び出しています。


今日の名言
自然に振る舞う態度ほど、身につけやすいものはない。ただ自分のことを忘れさえすればよい。
「こういうふうに見て欲しい」という気持ちを忘れさえすればよい。
                                          デール・カーネギー

家から出るときは、いつでもあごを引いて頭をまっすぐに立て、できる限り大きく呼吸をすること。
日光を吸い込むのだ。友人には笑顔をもって接し、握手には心をこめる。誤解される心配などせず、
敵のことに心を煩わさない。やりたいことをしっかりと心の中で決める。そして、まっしぐらに目標に
向かって突進する。大きな素晴らしいことをやり遂げたいと考えそれを絶えず念頭に置く。すると、
月日の経つにしたがって、いつの間にか念願を達成するのに必要な機会が自分の手の中に
握られていることに気がつくだろう。あたかも珊瑚虫が潮流から養分を摂取するようなものである。
また、有能で、真面目で、他人の役に立つ人物になることを心がけ、それを常に忘れないでいる。
すると、日の経つにしたがって、その様な人物になっていく。-心の働きは絶妙なものである。
正しい精神状態、すなわち勇気、率直、明朗さを常に持ち続けること。正しい精神状態は優れた
創造力を備えている。全ての物事は願望から生まれ、心からの願いは全てかなえられる。
人間は、心がけたとおりになるものである。あごを引いて頭をまっすぐに立てよう。
神となるための前段階-それが人間なのだ。
                                          エルバート・ハバート