C++演算子の再ロード——二元演算子の再ロード
14464 ワード
1、二元オペレータを再ロードする方法
バイナリ演算子はバイナリ演算子とも呼ばれ、+-*/などの2つのオペランドを必要とする演算子です.
演算子のリロードには、クラスの非静的メンバー関数、クラスのメタ関数、一般関数の3つの方法があります.
例えば2つのオペランドaとbがあり、二元演算子?(二元演算子を表す)、a?bの操作は以下の2つの形式の1つとして解釈される
1つ目の形式は、演算子がクラスに再ロードされる非静的メンバー関数です.
この方法では、演算子の左側のオペランド(すなわち、最初のオペランドa)がオブジェクトである必要があります.operator?このオブジェクトの非静的メンバー関数です
パラメータは1つしかありません.
2つ目の形式は、演算子がクラスに再ロードされる友元関数または一般関数です.
この方式には2つのパラメータが必要で、
クラスに再ロードされる友元関数と一般関数の違いは、クラスの友元関数がクラスのプライベートメンバーに直接アクセスでき、一般関数は使用できません.
2、適用例(対象?対象)
次の例ではcomplexクラスComplexA、ComplexB、ComplexCの3つがあり、3つのクラスには加算減算演算子が再ロードされています.
ここで、ComplexAはクラスの非静的メンバー関数方式でリロードされ、ComplexBはクラスの友元関数方式でリロードされ、ComplexCは通常の関数方式でリロードされる.
複数の加減乗除演算のアルゴリズムは問題があり、リロード方法を説明する例にすぎないことに注意しなければならない.
また、リロード関数のパラメータはconstキーワードで限定するのが望ましいが、戻り値がconstで限定されるかどうかは、C 3=+(C 1+C 2)を許可する場合など、あなたの設計に依存する必要がある.cosntで限定することはできない.
異なるタイプのオブジェクト間の操作については、通常は意味がありません.
3、適用例(オブジェクト?基本データ型or基本データ型?オブジェクト)
上記の例では、オブジェクトとオブジェクトの間の演算子のリロードですが、オブジェクト+char/int/float/double、または逆にchar/int/float/double+オブジェクトが必要な場合は、上記のプログラムのリロード方式は適用されません.
次のプログラムに示すように、新しいリロードを定義する必要があります.
バイナリ演算子はバイナリ演算子とも呼ばれ、+-*/などの2つのオペランドを必要とする演算子です.
演算子のリロードには、クラスの非静的メンバー関数、クラスのメタ関数、一般関数の3つの方法があります.
例えば2つのオペランドaとbがあり、二元演算子?(二元演算子を表す)、a?bの操作は以下の2つの形式の1つとして解釈される
//a ? b
a.operator?(b); //
operator?(a, b); //
1つ目の形式は、演算子がクラスに再ロードされる非静的メンバー関数です.
この方法では、演算子の左側のオペランド(すなわち、最初のオペランドa)がオブジェクトである必要があります.operator?このオブジェクトの非静的メンバー関数です
パラメータは1つしかありません.
2つ目の形式は、演算子がクラスに再ロードされる友元関数または一般関数です.
この方式には2つのパラメータが必要で、
クラスに再ロードされる友元関数と一般関数の違いは、クラスの友元関数がクラスのプライベートメンバーに直接アクセスでき、一般関数は使用できません.
2、適用例(対象?対象)
次の例ではcomplexクラスComplexA、ComplexB、ComplexCの3つがあり、3つのクラスには加算減算演算子が再ロードされています.
ここで、ComplexAはクラスの非静的メンバー関数方式でリロードされ、ComplexBはクラスの友元関数方式でリロードされ、ComplexCは通常の関数方式でリロードされる.
複数の加減乗除演算のアルゴリズムは問題があり、リロード方法を説明する例にすぎないことに注意しなければならない.
また、リロード関数のパラメータはconstキーワードで限定するのが望ましいが、戻り値がconstで限定されるかどうかは、C 3=+(C 1+C 2)を許可する場合など、あなたの設計に依存する必要がある.cosntで限定することはできない.
異なるタイプのオブジェクト間の操作については、通常は意味がありません.
#include <iostream>
using namespace std;
class ComplexA
{
public:
// (Default constructor)
ComplexA(){cout<<"Default Constructor"<<endl;}
// (The constructor with parameters)
ComplexA(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
// (Copy constructor)
ComplexA(const ComplexA& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
// (destructor)
~ComplexA(){cout<<"Destructor"<<endl;}
//Operator Overload : +
ComplexA operator+(ComplexA& ref)
{
return ComplexA(real + ref.real, image + ref.image);
}
//Operator Overload : -
ComplexA operator-(ComplexA& ref)
{
return ComplexA(real - ref.real, image - ref.image);
}
//Operator Overload : *
ComplexA operator*(ComplexA& ref)
{
return ComplexA(real * ref.real, image * ref.image);
}
//Operator Overload : /
ComplexA operator/(ComplexA& ref)
{
return ComplexA(real / ref.real, image / ref.image);
}
//display
void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
private:
double real; //
double image; //
};
class ComplexB
{
public:
// (Default constructor)
ComplexB(){cout<<"Default Constructor"<<endl;}
// (The constructor with parameters)
ComplexB(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
// (Copy constructor)
ComplexB(const ComplexB& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
// (destructor)
~ComplexB(){cout<<"Destructor"<<endl;}
//Operator Overload : +
friend ComplexB operator+(ComplexB& ref1, ComplexB& ref2)
{
return ComplexB(ref1.real + ref2.real, ref1.image + ref2.image);
}
//Operator Overload : -
friend ComplexB operator-(ComplexB& ref1, ComplexB& ref2)
{
return ComplexB(ref1.real - ref2.real, ref1.image - ref2.image);
}
//Operator Overload : *
friend ComplexB operator*(ComplexB& ref1, ComplexB& ref2)
{
return ComplexB(ref1.real * ref2.real, ref1.image * ref2.image);
}
//Operator Overload : /
friend ComplexB operator/(ComplexB& ref1, ComplexB& ref2)
{
return ComplexB(ref1.real / ref2.real, ref1.image / ref2.image);
}
//display
void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
private:
double real; //
double image; //
};
class ComplexC
{
public:
// (Default constructor)
ComplexC(){cout<<"Default Constructor"<<endl;}
// (The constructor with parameters)
ComplexC(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
// (Copy constructor)
ComplexC(const ComplexC& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
// (destructor)
~ComplexC(){cout<<"Destructor"<<endl;}
//Get Data
double GetReal(void){return real;}
double GetImage(void){return image;}
//display void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
private:
double real; //
double image; //
};
//Operator Overload : +
ComplexC operator+(ComplexC& ref1, ComplexC& ref2)
{
return ComplexC(ref1.GetReal() + ref2.GetReal(), ref1.GetImage() + ref2.GetImage());
}
//Operator Overload : -
ComplexC operator-(ComplexC& ref1, ComplexC& ref2)
{
return ComplexC(ref1.GetReal() - ref2.GetReal(), ref1.GetImage() - ref2.GetImage());
}
//Operator Overload : *
ComplexC operator*(ComplexC& ref1, ComplexC& ref2)
{
return ComplexC(ref1.GetReal() * ref2.GetReal(), ref1.GetImage() * ref2.GetImage());
}
//Operator Overload : /
ComplexC operator/(ComplexC& ref1, ComplexC& ref2)
{
return ComplexC(ref1.GetReal() / ref2.GetReal(), ref1.GetImage() / ref2.GetImage());
}
int main(void)
{
ComplexA C1(2,4), C2(1, 2), C3;
C3 = C1 + C2; C3.display();
C3 = C1 - C2; C3.display();
C3 = C1 * C2; C3.display();
C3 = C1 / C2; C3.display();
cout <<"--------------------------------------"<<endl;
ComplexB C4(2,4), C5(1, 2), C6;
C6 = C4 + C5; C6.display();
C6 = C4 - C5; C6.display();
C6 = C4 * C5; C6.display();
C6 = C4 / C5; C6.display();
cout <<"--------------------------------------"<<endl;
ComplexC C7(2,4), C8(1, 2), C9;
C9 = C7 + C8; C9.display();
C9 = C7 - C8; C9.display();
C9 = C7 * C8; C9.display();
C9 = C7 / C8; C9.display();
return 0;
}
3、適用例(オブジェクト?基本データ型or基本データ型?オブジェクト)
上記の例では、オブジェクトとオブジェクトの間の演算子のリロードですが、オブジェクト+char/int/float/double、または逆にchar/int/float/double+オブジェクトが必要な場合は、上記のプログラムのリロード方式は適用されません.
次のプログラムに示すように、新しいリロードを定義する必要があります.
#include <iostream>
using namespace std;
class ComplexD
{
public:
ComplexD(double re = 0, double im = 0):real(re),image(im){}
ComplexD operator+(ComplexD& ref){return ComplexD(real+ref.real, image+ref.image);};
ComplexD operator+(int a){cout<<"IN\t int \t\t";return ComplexD(real+a, image);};
ComplexD operator+(double d){cout<<"IN\t double \t";return ComplexD(real+d, image);};
ComplexD operator+(float f){cout<<"IN\t float \t\t";return ComplexD(real+f, image);};
void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
double GetReal(void){return real;}
double GetImage(void){return image;}
private:
double real;
double image;
};
ComplexD operator+(int a, ComplexD& ref){cout<<"OUT\t int \t\t";return ComplexD(ref.GetReal()+a, ref.GetImage());};
ComplexD operator+(double d, ComplexD& ref){cout<<"OUT\t double \t";return ComplexD(ref.GetReal()+d, ref.GetImage());};
ComplexD operator+(float f, ComplexD& ref){cout<<"OUT\t float \t\t";return ComplexD(ref.GetReal()+f, ref.GetImage());};
int main(void)
{
ComplexD D1(2,4), D2;
D2 = D1 + 2; D2.display();
D2 = D1 + 2.1f; D2.display();
D2 = D1 + 2.1; D2.display();
D2 = 2 +D1; D2.display();
D2 = 2.1f + D1; D2.display();
D2 = 2.1 +D1; D2.display();
return 0;
}