2014年4月10日木曜日

C++ 代入演算子のオーバーロード





前回の演算子のオーバーロードに続いて、

今度は代入演算子をオーバーロードします。







operator= ()関数は、オブジェクト同士の代入が行われたときに呼び出されますが、

演算子のオーバーロードと同様に、operator= ()関数をオーバーロードして

クラスを代入する新しい = (代入演算子)を定義してみます。

では、さっそくサンプルプログラムです。

#include <iostream>
#include <string.h>

using namespace std;

class Person {
public:
    Person() {
        m_StrName = NULL;
    }
    Person(char *StrName) {
        // 勝手に128文字までに制限
        int nLen = strnlen(StrName, 128);
        m_StrName = new char[nLen + 1];
        strncpy(m_StrName, StrName, nLen + 1);
    }
    ~Person() {
        if (m_StrName != NULL) {
            delete [] m_StrName;
            m_StrName = NULL;
        }
    }
    Person & operator=(const Person & Psn);
    char *GetPersonName() {
        return m_StrName;
    }
private:
    char *m_StrName;
};

// 代入演算子のオーバーロード
Person & Person::operator=(const Person &Psn)
{
    // 自分自身の代入では、何もしない
    if (this == &Psn) return *this;

    // それまでのメモリを解放
    if (m_StrName != NULL) {
        delete [] m_StrName;
        m_StrName = NULL;
    }

    // 新しくメモリを確保して、文字列をコピーする
    // やはりここでも128文字制限
    int nLen = strnlen(Psn.m_StrName, 128);
    m_StrName = new char[nLen + 1];
    strncpy(m_StrName, Psn.m_StrName, nLen + 1);

    return *this;
}

int main(void)
{
    Person Psn1((char *)"ABCDEFG");
    Person Psn2((char *)"TUVWXYZ");

    cout << Psn1.GetPersonName() << endl;
    cout << Psn2.GetPersonName() << endl;

    // 代入する 
    Psn1 = Psn2;

    cout << "---" << endl;

    cout << Psn1.GetPersonName() << endl;
    cout << Psn2.GetPersonName() << endl;

    return 0;
}

実行結果
# ./test
ABCDEFG
TUVWXYZ
---
TUVWXYZ
TUVWXYZ


ABCDEFGという名前が代入によってTUVWXYZに変わったという
例によって、あまりおもしろくないプログラムです。(^_^;)

ただ、デフォルトのoperator= ()ではメモリ確保などは行われないため
一応独自の動作が定義できています。

代入のところでは、Psn1オブジェクトのoperator= () が呼ばれ、
Psn2オブジェクトが引数に入るという動きになっています。

そしてoperator= ()が自分自身を返すのは、Psn1 = Psn2 という式が
さらに代入される場合があることを考慮しているからです。


ところで、Person Psn3 = Psn2; のようなオブジェクト生成時の
初期化の場合は、コピーコンストラクタが呼ばれます。
似ているので注意しておきたいところです。(^_^;)


今日の名言
常に現在の時間にしっかりしがみつけ。刻一刻すぎていく時間には、無限の価値がある。
私は現在に自己の全てを賭けている。一枚のトランプに人が大金をかけるように。
私は現在をそっくりそのままで、できるだけ高価なものにしようと努力しているのだ。
                            ヨハン・ウォルフガング・フォン・ゲーテ

今ここで征服できない時間は、永久に征服できない。今ここで楽しめない人生は、
永久に楽しめない。今ここで賢明な生活を送らなければ、永久に賢明な生活は
できない。過去はもはや存在せず、未来は誰にも分からないのだから。
                            デイヴィッド・グレイソン

もし、悩みに関して古今の大哲学者が書いた言葉の全てを要約すれば、次の
二句に尽きる。
「橋のたもとに行き着くまでは橋を渡るな」、「覆水盆に返らず」
                            デール・カーネギー

ありていに言えば、現在に生きる者はごく少ない。誰も彼も、現在以外の時に
生きるつもりなのだ。
                            ジョナサン・スウィフト