第24章 同姓同名3

 今回も前回に引き続き演算子のオーバーロードについてやっていきます。今回は戻り値も利用してみましょう。


 では、今回の要点です。


 では、いってみましょう。


 例えば、/ 演算子を考えてみましょう。これは2つの項の割り算をするだけではなく、その結果を渡してくれます。

 operator 関数には普通の関数と同じく戻り値があるので、ここで結果を返してやることができそうです。

 今回は、この戻り値を利用してみようと思います。


 CIntArray では Get, Set 関数を使って配列の要素を扱ってきました。でも、配列クラスと言うからには [ ] を使って要素を扱いたいものです。

 [ ] は2項演算子です。ということで、[ ] 演算子をオーバーロードすればなんとかなりそうです。<オブジェクト>[<引数>] という割り振りになります。

 しかし、

array[0] = 0;

というように、代入もできないと困ります。ところが array[0] は関数になります。関数に代入なんてできるのでしょうか?

 実は、戻り値を参照にすると、関数に代入できます。まぁ、実際に代入の対象になっているのは関数ではなく戻り値なのですが。

 詳しくは第3部第8章で話しているので、そちらを参考にして下さい。

 ここで返すのは要素への参照です。要素への参照を返せば、値の取得もできますし、要素への代入もできますね。

 ということで、やってみましょう。

プログラム1
// IntArray.h
class CIntArray
{
    // メンバへのアクセス関数
public:
    int& operator [](int index);  // メンバのアクセス
};
プログラム2
// IntArray.cpp
// メンバのアクセス
int& CIntArray::operator [](int index)
{
    CheckIndex(index);
    return m_pnum[index];
}

 しかし、このままでは const オブジェクトになったときに使えません。そこで、const オブジェクト用の関数も作りましょう。

プログラム1
// IntArray.h
class CIntArray
{
    // メンバへのアクセス関数
public:
    int operator [](int index) const;  // メンバのアクセス
};
プログラム2
// IntArray.cpp
// メンバのアクセス
int CIntArray::operator [](int index) const
{
    CheckIndex(index);
    return m_pnum[index];
}

 「あれ? 引数が同じなのにオーバーロードできるの?」と思うかもしれませんが、大丈夫です。const メンバ関数かどうかの違いだけでもオーバーロードできます。

 const オブジェクトから呼べば const メンバ関数が、非 const オブジェクトから呼べば非 const メンバ関数が呼び出されます。

 そして、const オブジェクトなので要素への代入はできなくて構いません。なので、戻り値はただの int になっています。これはごく自然に受け入れられる使い方ですね。


 もう1つ、配列クラスというからには int 型の配列を引数にとるような関数にそのまま渡したいですね。

例)
// int Average(const int* pnData, int nNumOf);
Average(array, array.NumOf());

 ただ、範囲外の要素への操作を禁止している以上は、渡せるのは const int* へだけで、int* には安全のため渡せないようにしたいですね。

 こういうときは (const int*) というキャスト演算子をオーバーロードすればいいのです。

 キャストも演算子なのでオーバーロードできます。キャストは1項演算子で、(const int*)<オブジェクト> というそのままの割り当てになります。

 では、やってみましょう。

プログラム
// IntArray.h
class CIntArray
{
    // メンバへのアクセス関数
public:
    operator const int*() const;  // 配列の直接参照
};

// 配列の直接参照
inline CIntArray::operator const int*() const
{
    return m_pnum;
}

 おや? 戻り値の型がないですね。

 キャストでは、何にキャストするかが分かれば戻り値の型も自動的に決まってしまうので、戻り値の型は書きません

 それ以外は特に問題はないと思います。


 以上をまとめると、


となります。

 次回は、前回予告したとおりのことをやりたいと思います。それでは。


第23章 同姓同名2 | 第25章 これ。

Last update was done on 2000.8.28

この講座の著作権はロベールが保有しています