プログラミング言語 C++ における演算子オーバーロードの糖衣構文的な解釈と、フレンド関数による解決
演算子オーバーロードの糖衣構文的な解釈
#include <iostream>
using namespace std;
class coord {
int x, y;
public:
coord() : x(0), y(0) {}
coord(int i, int j) : x(i), y(j) {}
void show() { cout << "x = " << x << ", y = " << y << endl; }
coord operator+(coord position);
coord add(coord position);
};
coord coord::operator+(coord position)
{
coord temp;
temp.x = this->x + position.x;
temp.y = this->y + position.y;
return temp;
}
coord coord::add(coord position)
{
coord temp;
temp.x = this->x + position.x;
temp.y = this->y + position.y;
return temp;
}
int main()
{
coord position_a(10, 10), position_b(5, 3);
coord position_m = position_a + position_b;
position_m.show(); // => x = 15, y = 13
coord position_n = position_a.add(position_b);
position_n.show(); // => x = 15, y = 13
return 0;
}
※ 説明をシンプルにするために参照渡しやconst修飾は省略しています。
上記のコードにおいて、 +演算子のオーバーロード
position_a + position_b
は
position_a.operator+(position_b)
の糖衣構文(シュガーシンタックス)です。
メンバー関数名 "operator+" を "add" と意訳すれば、下記のように書き換えることができます。
position_a.add(position_b)
さらに下記のような演算子オーバーロードも考えることができます。
position + 10
position.add(10)
しかし、下記のような演算子のオーバーロードは『メンバー関数』として定義することはできません。
10 + position
10.add(position)
フレンド関数の演算子オーバーロード
そこで下記のようにフレンド関数の演算子オーバーロードをつかえば二項演算子の交換法則を正しく実装することができます。フレンド関数を使う目的はprivateなメンバー変数にアクセスすることにあります。もしメンバー変数がpublicであれば、必ずしもフレンド関数である必要性はありません。メンバー変数にアクセスできる非メンバーの関数でありさえすれば交換法則を実現することができます。
#include <iostream>
using namespace std;
class coord {
int x, y;
public:
coord() : x(0), y(0) {}
coord(int i, int j) : x(i), y(j) {}
void show() { cout << "x = " << x << ", y = " << y << endl; }
friend coord operator+(const coord& pos, const int& dist);
friend coord operator+(const int& dist, const coord& pos);
};
coord operator+(const coord& pos, const int& dist)
{
coord temp;
temp.x = pos.x + dist;
temp.y = pos.y + dist;
return temp;
}
coord operator+(const int& dist, const coord& pos)
{
coord temp;
temp.x = pos.x + dist;
temp.y = pos.y + dist;
return temp;
}
int main()
{
coord position(5, 3);
coord position_m = position + 5;
position_m.show(); // => x = 10, y = 8
coord position_n = 5 + position ;
position_n.show(); // => x = 10, y = 8
return 0;
}