ゼロからc++の演算子のリロードとタイプ変換を学習する

2786 ワード

演算子の再ロード:
演算子のリロードとは:
リロードされた演算子は特殊な名前の関数で、名前はoperatorキーにリロードする演算子を加えたもので、operator+、他の関数と同様に、リロードされた演算子にも戻りタイプ、パラメータリスト、関数体が含まれます.
演算子のリロードの詳細:
(1)演算子関数がメンバー関数である場合、thisは左側の演算オブジェクトにバインドされます.メンバー演算子関数の(明示的な)パラメータの数は、演算オブジェクトの数より1つ少ない.
(2)リロードされた関数呼び出し演算子operator()以外のリロード演算子にはデフォルトの実パラメータは含まれません.
(3)既存の演算子のみをリロードし,新しい演算子を発明する権限がない.
(4)演算子のリロードは演算子の優先度を変更しない.
再ロードできる演算子:
+   -    *   /    %    ^    &    |    ~    !    ,    =        <=    >=   ++    --    <>    ==    !=    &&    ||   ++    -=   /=    %=    &=    ^=    |=
*=    <<=    >>=    []    ()    ->    ->*    new    new[]    delete    delete[]
再ロードできない演算子:
           ::            .*              .            ?:
リロード演算子を呼び出します.
data1 + data2;    //     
operator+(data1,data2);   //       
//         ,         operator+,  data1 data2      
data3 += data4      //        
data3.operator+=(data2);         //           
//              operator+= , this   data3   , data4          

メンバー関数および非メンバー関数としての再ロード演算子の選択:
(1)単項演算子はメンバー関数として(必須ではない)(2)=()[->->*はメンバー関数でなければならない(3)複合付与演算子はメンバー関数として(4)これらの2元でない他のすべての演算子は非メンバー関数として
代入演算子の標準フォーマットの再ロード:
T&T::operator=(const T&rhs){if(this!=&rhs)//自身が付与するオブジェクトに等しくないことを検出{//perform assignment}return*this;}
サンプルコード:
class Integer {
public :
	Integer(int n = 0):i(n){}
	const Integer operator+(const Integer& n) const {
		return Integer(i + n.i);
	}
	int print() { return i; }
private:
	int i;
};
int main()
{
	Integer x(5), y(10), z1,z2,z3;

	z1 = x + y;                  //    z = x.operator+(y)
	z2 = x + 3;                  //Integer         Integer(3):i(3){}, z = x.operator+(3)
	//z3 = 3 + y;                  //     ,3          int +,y  int  Integer       y  int   
 
	cout <

タイプ変換:
タイプ変換とは:
タイプ変換演算子は、クラスの特殊なメンバー関数であり、クラスタイプを別のタイプに変換します.標準フォーマット:operator type()const;//typeはあるタイプを表す
タイプ変換演算子とコンストラクション関数:
タイプ変換とコンストラクション関数はいずれもT=>Cのクラスタイプ変換を行うことができる
(1)T(C)/コンストラクション関数(2)operator T()const;//Cでのタイプ変換
class Orange;
class Apple {
public:
	operator Orange() const {}    //    
};

class Orange {
public:
	Orange(Apple) {}       //         
};

void func(Orange){}     //func     Orange
int main()
{
    Apple ap;
    func(ap);                  //     ,  :          Apple Orange   
    return 0;
}
しかし、コンストラクション関数とタイプ変換が同時に存在する場合、コンパイラはどの関数を使用して変換すべきか分からず、エラーが発生します.
解決方法:(1)関数の1つを削除します.
(2)コンストラクション関数の前にexplicitキーワードを付けると,このコンストラクション関数はコンストラクションにのみ使用でき,自動タイプ変換には使用できないことを示す.
まとめ:
タイプ変換関数の過度な使用は避けるべきで、誤導性を形成しやすいため、意外なことを防止しなければならない.
一般的には、タイプ変換を呼び出すために専門的な関数を使用して、プログラムが何が起こったのかをより一目瞭然にします.