c++の演算子リロードベース
3751 ワード
1、定義:リロードとは、新たな意味を与えることである.関数のリロードとは、既存の関数に新しい意味を与え、新しい機能を実現させることである.そのため、1つの関数名は異なる機能を表す関数、すなわち「1名多用」に使用することができる.
2、なぜ演算子で再ロードするのか:
複数のクラスで例を挙げる:Complex c 3=c 1+c 2;
理由Complexはユーザーのカスタムタイプで、コンパイラはどのように加減コンパイラを行うか全然知らないので、ユーザーに自分で完成させるメカニズムを提供して、カスタムタイプの加減操作、このメカニズムは演算子のリロードメカニズムで、演算子のリロードの本質は1つの関数です.
3、演算子の再ロード基礎
(1)演算子の再ロードの2つの方法:クラスメンバー関数とグローバル関数
1)二元演算子のリロード(+、-、*、/などの演算子)(以下はクラスメンバー関数でリロード)
2)単項演算子のリロード(++、--など)(以下はグローバル関数でリロード)
(2)演算子リロード関数名を定義するには:グローバル関数、クラスメンバー関数メソッド実装演算子リロードステップ
1)オペレータリロードが関数であることを認めるには、関数名operator+()を書き出します.
2)オペランドにより、関数パラメータを書き出します
3)業務によって、関数の戻り値を改善する(関数が参照を返すかポインタ要素を返すかを見る)、及び関数業務を実現する
(3)ユーティリティー関数によるオペレータ再ロードの適用シーン
1)友元関数とメンバー関数の選択方法:
①左オペランドのクラスを変更できない場合は、グローバル関数を使用してリロード
②=,[],(),->オペレータはメンバー関数のみでリロードできます
2)友元関数で<<演算子を再ロードする
(4)友元関数リロードオペレータ使用上の注意点
1)友員関数リロード演算子は演算子の左右のオペランドタイプが異なる場合によく用いられる
2)最初のパラメータに暗黙的な変換が必要な場合は、メンバー関数を使用して演算子を再ロードするのが正しい
3)友員関数はthisポインタがなく、必要なオペランドはパラメータ表で明示的に宣言しなければならず、タイプの暗黙的な変換を容易に実現できる.
4)C++のメンバー関数でリロードできない演算子は、=、()、[]、->
4、&&&と演算子を再ロードしない
1)&&&||内蔵ショートルールを実現
2)オペレータリロードは関数リロードで行う
3)C++の関数パラメータはいずれも評価され,ショートルールは実現できない.
2、なぜ演算子で再ロードするのか:
複数のクラスで例を挙げる:Complex c 3=c 1+c 2;
理由Complexはユーザーのカスタムタイプで、コンパイラはどのように加減コンパイラを行うか全然知らないので、ユーザーに自分で完成させるメカニズムを提供して、カスタムタイプの加減操作、このメカニズムは演算子のリロードメカニズムで、演算子のリロードの本質は1つの関数です.
3、演算子の再ロード基礎
(1)演算子の再ロードの2つの方法:クラスメンバー関数とグローバル関数
1)二元演算子のリロード(+、-、*、/などの演算子)(以下はクラスメンバー関数でリロード)
#include
class test1_1
{
public:
test1_1(int a);
int operator+(test1_1 &obj);
int operator+(const int a);
int operator-(test1_1 &obj);
int operator-(const int a);
int operator*(test1_1 &obj);
int operator*(const int a);
int operator/(test1_1 &obj);
int operator/(const int a);
private:
int m_a;
};
test1_1::test1_1(int a)
{
m_a = a;
}
int test1_1::operator+(test1_1 &obj)
{
return (m_a + obj.m_a);
}
int test1_1::operator+(const int a)
{
return (m_a + a);
}
int test1_1::operator-(test1_1 &obj)
{
return (m_a - obj.m_a);
}
int test1_1::operator-(const int a)
{
return (m_a - a);
}
int test1_1::operator*(test1_1 &obj)
{
return (m_a * obj.m_a);
}
int test1_1::operator*(const int a)
{
return (m_a * a);
}
int test1_1::operator/(test1_1 &obj)
{
return (m_a / obj.m_a);
}
int test1_1::operator/(const int a)
{
return (m_a / a);
}
int main1_1()
{
test1_1 a1(10), a2(20);
int c = a1 * a2;
printf("c = %d
", c);
return 0;
}
2)単項演算子のリロード(++、--など)(以下はグローバル関数でリロード)
#include
class test4_1
{
friend test4_1 operator++(test4_1 &obj);
friend test4_1 operator++(test4_1 &obj, int);
friend test4_1 operator--(test4_1 &obj);
friend test4_1 operator--(test4_1 &obj, int);
public:
test4_1(){}
test4_1(int a, int b)
{
this->a = a;
this->b = b;
}
void print()
{
printf("%d + %di
", this->a, this->b);
}
private:
int a;
int b;
};
test4_1 operator++(test4_1 &obj)
{
obj.a++;
obj.b++;
return obj;
}
test4_1 operator++(test4_1 &obj, int)
{
test4_1 tmp(obj.a, obj.b);
obj.a++;
obj.b++;
return tmp;
}
test4_1 operator--(test4_1 &obj)
{
obj.a--;
obj.b--;
return obj;
}
test4_1 operator--(test4_1 &obj, int)
{
test4_1 tmp(obj.a, obj.b);
obj.a--;
obj.b--;
return tmp;
}
int main4_1()
{
test4_1 t1(10, 20), t2;
t1++;
++t1;
t1--;
--t1;
t1.print();
return 0;
}
(2)演算子リロード関数名を定義するには:グローバル関数、クラスメンバー関数メソッド実装演算子リロードステップ
1)オペレータリロードが関数であることを認めるには、関数名operator+()を書き出します.
2)オペランドにより、関数パラメータを書き出します
3)業務によって、関数の戻り値を改善する(関数が参照を返すかポインタ要素を返すかを見る)、及び関数業務を実現する
(3)ユーティリティー関数によるオペレータ再ロードの適用シーン
1)友元関数とメンバー関数の選択方法:
①左オペランドのクラスを変更できない場合は、グローバル関数を使用してリロード
②=,[],(),->オペレータはメンバー関数のみでリロードできます
2)友元関数で<<演算子を再ロードする
#include
using namespace std;
class test5_1
{
friend ostream & operator<a = a;
}
void print()
{
printf("a = %d
", this->a);
}
private:
int a;
};
ostream & operator<
(4)友元関数リロードオペレータ使用上の注意点
1)友員関数リロード演算子は演算子の左右のオペランドタイプが異なる場合によく用いられる
2)最初のパラメータに暗黙的な変換が必要な場合は、メンバー関数を使用して演算子を再ロードするのが正しい
3)友員関数はthisポインタがなく、必要なオペランドはパラメータ表で明示的に宣言しなければならず、タイプの暗黙的な変換を容易に実現できる.
4)C++のメンバー関数でリロードできない演算子は、=、()、[]、->
4、&&&と演算子を再ロードしない
1)&&&||内蔵ショートルールを実現
2)オペレータリロードは関数リロードで行う
3)C++の関数パラメータはいずれも評価され,ショートルールは実現できない.
#include
#include
using namespace std;
class Test
{
int i;
public:
Test(int i)
{
this->i = i;
}
Test operator+ (const Test& obj)
{
Test ret(0);
cout<