C++入門 補足5
演算子の多重定義
ところが、実は「コピーコンストラクタ、代入演算子」のところで「演算子の多重定義」はすでにやっていました。つまり、「=」という演算子はC++で定義されている「演算子」(というもの)なのですが、自分のクラス用に、定義し直したのが、「演算子=の多重定義」なのです。
演算子も実は特別な形をした関数です。ということは、メンバ関数とグローバルな関数があるように、演算子にもクラスのメンバであるのものとそうでないものがあります。代入演算子はクラスメンバの例でした。
それで、ここでは、メンバでない演算子の例を見ましょう。毎度のことですが、「○○とは、そもそも、、、」なんて説明を読んだり考えたりするより、下の具体例を見て、そんなものかと理解してください。
では、まず、下のようなクラスを考えたとしましょう。何のことはない、整数を二つデータに持つクラスです。
class Thing { int data1; int data2; public: Thing():data1(0),data2(0){} Thing(int d1, int d2):data1(d1),data2(d2){} int GetData1() const {return data1;} void SetData1(int d){data1=d;} int GetData2() const {return data2;} void SetData2(int d){data2=d;} };
もちろん、上のクラスは単純すぎて、役に立ちそうもありませんが、本当は、平面上の点の座標とか、2次元ベクトルとか、まあそんなものの一部と想像してください。本論とあまり関係ないですが、コンストラクタが二つあるのはよいでしょうか?ひとつは、引数なしのコンストラクタで、つまり、引数を与えないと、data1もdata2も0になってしまうという定義です。もちろん、引数付きのコンストラクタは、それぞれdata1とdata2を初期化するものです。
さて、このクラスのインスタンス同士の足し算をしたくなったとします。「足し算」とは、二つのデータのそれぞれの足し算としましょう。つまり、
Thing x(10,20),y(30,40); //...いろいろあって... Thing a=x+y;
これは、Thing同士を足して、新たなThingを作るということです。こういうことが必要な場合もあるでしょう。これをするには、
Thing operator+(Thing a, Thing b)
というものを定義すればよいのです。「へっ???なんだ、こりゃ?」が私が最初にこの手のものを見たときの反応です。はじめて見るとなんだかわかりませんよね。実際は、わかるとかわからないの問題ではなく、「こうすればよい」ということなんですが、、、。
一応、それらしく説明すると、はじめにあるThingは、足し算の結果がThingになるという意味です。(よりC++らしく言うと、足し算の結果戻される値はThingということです。)Thing
aとThing bは関数の引数にあたるもので、aとbを足すときという意味です。
ここまでの説明ですっきりするはずはありません。むしろ、以下の実際のコードを実行して、よくよく眺めてみてください。そうすれば、わかると思います。^^)
#include <iostream.h> class Thing { int data1; int data2; public: Thing():data1(0),data2(0){} Thing(int d1, int d2):data1(d1),data2(d2){} //constはこの関数がデータを変更しないという意味 int GetData1() const {return data1;} void SetData1(int d){data1=d;} int GetData2() const {return data2;} void SetData2(int d){data2=d;} }; Thing operator+(Thing a, Thing b) { //aとbのデータを足しあわせたThingを作る Thing temp(a.GetData1()+b.GetData1(), a.GetData2()+b.GetData2()); //できたThingを戻す return temp; } void main() { Thing x(10,20), y(30,40); Thing a=x+y; cout<<a.GetData1()<<endl; cout<<a.GetData2()<<endl; }
つまり、こういうものなんです。
ところで、上の足し算より、参照を使った
Thing operator+(Thing& a, Thing& b)
の方が、効率が良さそうです。しかし、もし、aやbのデータを変更するつもりがないのなら、
Thing operator+(const Thing& a, const Thing& b)
の方が良いのです。(というか、特別な理由がない限り、上のようにconstをつけるようにしましょう。)