2013年10月21日月曜日

C++ コピーコンストラクタ その1

なんだか怪しいフレーズが飛び出してきました(^_^;)
コピーコンストラクタとは、オブジェクトの生成時に初期化を行う場合に呼び出されます。
あるオブジェクトを生成するとき、既にあるオブジェクトの内容で初期化したい、という
状況があったとします。まさに、このときがコピーコンストラクタの出番になります。
したがって、コピーコンストラクタは引数に初期化元のオブジェクトを受け取ります。^^
では、例をみていきます。

Person psn1;             //Personクラスのオブジェクトpsn1を生成
        :
Person psn2(psn1);    //Personクラスのオブジェクトpsn2を生成
                               //ただし、内容はpsn1で初期化する

ここではpsn2の生成時に、コピーコンストラクタが呼ばれます。
初期化するオブジェクトと同じクラスのオブジェクトであることに注意してください。

別の記述方法として、この様に書くこともできます。

Person psn2 = psn1;    //Person psn2(psn1); と同じようにコピーコンストラクタが呼ばれます。

なお、既にあるオブジェクトに別のオブジェクトを代入する場合は、コピーコンストラクタではなく
operator=() というメンバ関数を呼び出します。 operator=()関数は後述します。(^_^;)

Person psn1;    //Personクラスのオブジェクトpsn1を生成する
Person psn3;    //Personクラスのオブジェクトpsn3を生成する
psn3 = psn1;    //psn1をpsn3に代入する

なんだかごっちゃになってしまいそうですが、要注意です。
初期化と代入は、別だということを理解し、しっかりと区別してください。

コピーコンストラクタの宣言と定義する例
コピーコンストラクタの引数の型は、自分のクラスと同じになります。
また、const形式の参照にします。
        :
class Person {
public:
    Person();
    Person(const Person &psn);    //コピーコンストラクタの宣言
    ~Person() {
        if (m_pName != NULL) {
            delete [] m_pName;
            m_pName = NULL;
        }
    }
private:
    char *m_strName;
};
        :
//コピーコンストラクタの定義
Person::Person(const Person &psn)
{
    //メモリの確保
    //このサンプルでは人名は終端のNULL文字を含め32文字までと決めている
    m_strName = new(std::nothrow) char[strnlen(psn.m_strName, 31) + 1];
  if (m_strName != NULL) {
        //メンバ変数(人名)のコピー する
        strncpy(m_strName, psn.m_strName, strnlen(psn.m_pName, 32));
    }
}
        :
このように、メモリを確保する必要があれは、それを記述しなければなりません(^_^;)
これは、何気ないところですが要注意ポイントです。

なお、コピーコンストラクタを記述しない場合は、デフォルトのコピーコンストラクタが
用意されます。

次回の記事は、要注意ポイントと関連してコピーコンストラクタが必要な場合についてです。

今日の名言
失敗は、ある意味では成功に向かう本街道である。どこが間違っているかわかるたびに
真実とは何であるかを熱心に追求するようになる。そして新しい経験をするたびに、何らか
の誤りが明るみに出てくるから、その後は心して失敗を避けるようになる。
                                     ジョン・キーツ

苦難に勝る教育なし。
                                     ベンジャミン・ディズレーリ

困難にあって倒れるようでは、汝の力はまだ弱い。
                                     旧約聖書の格言

人生でもっとも大切な事は利益を活用する事ではない。それなら馬鹿にだってできる。
真に重要な事は損失から利益を生み出すことだ。このためには明晰な頭脳が必要になる。
そして、ここが分別ある人と馬鹿者との分かれ道になる。
                                     ウィリアム・ボリソー