C++のオペレータリロード詳細解析
#include
using namespace std;
int main()
{
int a = 2 , b = 3;
float c = 2.1f , d = 1.2f;
cout< cout< return 0;
}
オペレータ「+」がfloatとintの2種類の加算計算を完了するのを見ました.これがオペレータの再ロードです.これらの内蔵型のオペレータのリロードはすでに実現されていますが、今私たちが自分で書いたクラスでも類似の加算を実現するにはどうすればいいのでしょうか.たとえば現在、2つの点の加算を実現するには、横長座標を加算する点クラスpointがあります.この場合、オペレータのリロード関数を自分で書く必要があります.
#include
using namespace std;
class point
{
double x;
double y;
public:
double get_x()
{
return x;
}
double get_y()
{
return y;
}
point(double X = 0.0 , double Y = 0.0):x(X),y(Y){};
point operator +(point p);
};
// “+”
point point::operator +(point p)
{
double x = this->x + p.x;
double y = this->y + p.y;
point tmp_p(x,y);
return tmp_p;
}
int main()
{
point p1(1.2,3.1);
point p2(1.1,3.2);
point p3 = p1+p2;
cout< return 0;
}
二、オペレータのリロードを実現する2つの方法オペレータのリロードの実現方法は2つあり、すなわち「友元関数」または「クラスメンバー関数」を通過する.
1.ユーティリティー関数リロードオペレータのフォーマット:
class
{
friend operator ( );
};
// :
operator ( )
{
//
}
2.クラスメンバー関数はオペレータの再ロードのフォーマットを実現する:
class
{
public:
operator ( );
};
//
::operator ( )
{
//
}
そう言えば、この2つの実装方式の違いを比較するのに十分ではありません.ポイントクラスの「+」と「-」のリロードをそれぞれ2つの実装方式で書きます.コードは以下の通りです.
#include
using std::endl;
using std::cout;
class point
{
double x;
double y;
public:
double get_x()
{
return x;
}
double get_y()
{
return y;
}
point(double X = 0.0 , double Y = 0.0):x(X),y(Y){};
friend point operator -(point p1,point p2);
point operator +(point p);
};
// “-”
point operator -(point p1,point p2)
{
double x = p1.get_x() - p2.get_x();
double y = p1.get_y() - p2.get_y();
point p3(x,y);
return p3;
}
// “+”
point point::operator +(point p)
{
double x = this->x + p.x;
double y = this->y + p.y;
point tmp_p(x,y);
return tmp_p;
}
int main()
{
point p1(1.2,3.2);
point p2(1.1,3.1);
point p3 = p1+p2;
point p4 = operator-(p1,p2);
cout< cout< return 0;
}
ここは皆さんが見たかどうか分かりませんが、友元関数を使用して二元オペレータを再ロードする場合-「場合、形式パラメータは2つですが、クラスメンバー関数を使用する場合、形式パラメータは1つしかありません.この場合、クラスメンバー関数にthisポインタが存在するため、これは1つのパラメータに相当します.したがって、クラスメンバーがオペレータの再ロードを実現するために必要な形式パラメータは元より1つ少ないです.たとえば、クラスメンバー関数を使用して一元オペレータを実現する場合-.「パラメータは必要ありません.そのため、演算子のリロードには[],(),->および=を使用することはできません.
実際の開発では、単一演算子はメンバー関数として再ロードすることを推奨し、両目演算子は友元関数として再ロードすることを推奨します.通常、二重演算子をメンバー関数としてリロードするよりも友元関数としてリロードするほうが便利ですが、二重演算子はメンバー関数、たとえば付与演算子=としてリロードする必要がある場合があります.また、オブジェクト内部のステータスを変更する必要がある場合は、一般的にクラスメンバー関数を使用して変更することを選択できます.
三、演算子のリロードの原則このように見ると、演算子のリロードは簡単ですが、実際には演算子のリロードもいくつかの原則に従います.
1.C++では既存のC++演算子のみをリロードでき、ユーザー自身で新しい演算子を定義することはできません.
2.C++のほとんどの演算子は、メンバーアクセス演算子を除いてリロードできます.役割ドメイン演算子:、長さ演算子sizeofおよび条件演算子?:.
3.演算子のリロード後に演算子のオペランド(オペランド)の個数を変更することはできません.「+」は2つのオペランドを実装する演算子で、リロード後も両目演算子です.
4.リロードは、演算子の既存の優先度と既存の結合性を変更することはできません.
5.演算子のリロードは、すべてC++で定義された基本データではありません.これは、基本タイプのデータに使用される演算子の性質をユーザーが変更しないようにするためです.
四、なぜ演算子のリロードを行うのか演算子のリロードについてこんなに多くの原則に従うのか、なぜ演算子のリロードを行うのか.なぜoperator+()の代わりにadd()関数を書かないのですか??個人感覚C++で演算子のリロードをサポートするのは、内蔵データ型と統一した操作のため、例えば、c=a+bとc=add(a,b)と、どちらが直感的に見えるかは、明らかに前者です.また、intやdoubleなどの内蔵データ型のように、自分たちで定義したデータ型を操作するのが便利であることを望んでいます.この加算の例を挙げると少し悪いかもしれませんが、現在重荷を加えている演算子は[],<