【C++】C++のオペレータリロード

11113 ワード

C++のオペレータリロードはクラスオブジェクトの操作をより便利かつ直感的に行うことができるが,様々なオペレータリロードのルールや文法形式については,これまでどちらの上でstackoverflowで検索してきたのか,4,5回検索した後,毎回面倒に思ってまとめた.
オペレータリロードの一般的な構文
リロード方法は、クラスにリロードされたメンバー関数と、クラスにリロードされた友元関数の2つに分けられ、構文形式はそれぞれ次のとおりです.
//

class MyClass

{

public:

         operator    (    );

};



     MyClass::operator    (    )

{

    //    

}





//

class MyClass

{

public:

    friend      operator    (    );

};



     operator    (    )

{

    //    

}

 
オペレータの再ロードの3つの基本原則
  • オペレータの意味が明らかでない場合、または議論がある可能性がある場合は、オペレータを再ロードするべきではありません.オペレータの再ロードの代わりに関数を指定することを考慮します.
  • は、オペレータ固有の意味を常に堅持します.たとえば、+オペレータを表す意味a-bを再ロードすると、コンパイラはスムーズに通過するが、オペレータ使用者の予想とは大きく一致しない.
  • は、常に関連するすべてのオペレータを提供します.例えば、a+bがサポートされている場合、使用者は当然、a+=bを呼び出すことができることを望んでいる.接頭辞自己増加++aがサポートされている場合、接尾辞自己増加a−が提供される.abを提供します.

  • メンバー関数と非メンバー関数(メタ関数)の選択
    割り当てオペレータ(=)、下付きオペレータ([])、メンバーアクセスオペレータ(->)、および関数呼び出しオペレータ(())は、メンバー関数として再ロードする必要があります.
  • が1つのオペレータである場合、メンバー関数
  • として実装される.
  • は、二元オペレータである、かつ、その二元オペレータは、左右の操作数に応じて平等(例えば、演算オペレータ、関係オペレータ、ビットオペレータ等)である、非メンバー関数
  • として実現される.
  • が二元オペレータであり、左右のオペランドによって異なる場合、メンバー関数(例えば、+=、-=、*=、/=など)
  • として実現される.
    一般的なオペレータリロード
    たくさんお話ししましたが、最も重要なのは、一般的なオペレータの文法形式です.以下のようにします.
    #include <iostream>
    
    #include <string>
    
    using namespace std;
    
    class ClassType;
    
    
    
    //        (        )
    
    ostream& operator<< (ostream& os, const ClassType& object) {return os;}
    
    istream& operator>> (istream& is,       ClassType& object) {return is;} //   object    const  
    
    
    
    //     (       )
    
    ClassType& operator=  (const ClassType& object) {return *this;}
    
    ClassType& operator-= (const ClassType& object) {return *this;} 
    
    ClassType& operator*= (const ClassType& object) {return *this;}
    
    ClassType& operator/= (const ClassType& object) {return *this;}
    
    ClassType& operator%= (const ClassType& object) {return *this;}
    
    
    
    //      (          )
    
    ClassType operator+    (const ClassType& lhs, const ClassType& rhs);
    
    ClassType operator-    (const ClassType& lhs, const ClassType& rhs);
    
    ClassType operator*    (const ClassType& lhs, const ClassType& rhs);
    
    ClassType operator/    (const ClassType& lhs, const ClassType& rhs);
    
    ClassType operator% (const ClassType& lhs, const ClassType& rhs);
    
    
    
    //      (          )
    
    inline bool operator<     (const ClassType& lhs, const ClassType& rhs);
    
    inline bool operator<=    (const ClassType& lhs, const ClassType& rhs);
    
    inline bool operator>     (const ClassType& lhs, const ClassType& rhs);
    
    inline bool operator>=    (const ClassType& lhs, const ClassType& rhs);
    
    inline bool operator==    (const ClassType& lhs, const ClassType& rhs);
    
    inline bool operator!=    (const ClassType& lhs, const ClassType& rhs);
    
    
    
    //         (        )
    
    ClassType& operator++ () {return *this;}        //   ++,  :++iter
    
    ClassType& operator-- () {return *this;}
    
    ClassType operator++ (int) {return tmp;}        //   ++,  :iter++
    
    ClassType operator-- (int) {return tmp;}
    
    
    
    //      (         )
    
          TypeInContainer& operator[] (const size_t index)            //  const  
    
    const TypeInContainer& operator[] (const size_t index) const      // const   
    
    
    
    //        (*,->       )
    
    Class MyPtr
    
    {
    
              value_type& operator*();            // const  
    
        const value_type& operator*() const;      //const  
    
              value_type* operator->();
    
        const value_type* operator->() const;
    
    };
    
    
    
    //        
    
    struct MyClass
    
    {
    
        ClassType operator()(Type1 x1, Type2 x2)
    
        {
    
    
    
        }
    
    };

    参考文献:
  • Statckoverflow operator overloading discussion
  •  S.B.Lippman and J.Lajoie. C++Primer中国語版北京:人民郵電出版社、2011.430-453.
  • 随感而发:C++オペレータリロード