web-dev-qa-db-ja.com

postfix a ++とprefix ++ aの2つの異なる方法でoperator ++をオーバーロードする方法は?

Postfix a++とprefix ++aに対して2つの異なる方法でoperator ++をオーバーロードする方法は?

104
rookie

次のようになります。

class Number 
{
    public:
        Number& operator++ ()     // prefix ++
        {
           // Do work on this.   (increment your object here)
           return *this;
        }

        // You want to make the ++ operator work like the standard operators
        // The simple way to do this is to implement postfix in terms of prefix.
        //
        Number  operator++ (int)  // postfix ++
        {
           Number result(*this);   // make a copy for result
           ++(*this);              // Now use the prefix version to do the work
           return result;          // return the copy (the old) value.
        }
}; 
162
Martin York

違いは、operator ++のオーバーロードに対して選択する署名にあります。

関連する C++ FAQのこの主題に関する記事 から引用(詳細についてはそこにアクセスしてください):

class Number {
  public:
    Number& operator++ ();     // prefix ++: no parameter, returns a reference
    Number  operator++ (int);  // postfix ++: dummy parameter, returns a value
};

P.S.:このことを知ったとき、最初に見たのはダミーパラメータだけでしたが、実際には異なる戻り値の型がより興味深いです。 ++xが一般的にx++よりも効率的であると考えられる理由を説明するかもしれません

32
stakx

タイプTの2つの(プレフィックス/ポストフィックス)++演算子をオーバーロードするには、2つの方法があります。

オブジェクトメソッド:

これは、 "common" OOPイディオムを使用する最も簡単な方法です。

class T
{
    public :
        T & operator++() // ++A
        {
            // Do increment of "this" value
            return *this ;
        }

        T operator++(int) // A++
        {
           T temp = *this ;
           // Do increment of "this" value
           return temp ;
        }
} ;

オブジェクトの非メンバー関数:

これは別の方法です。関数が参照しているオブジェクトと同じ名前空間にある限り、コンパイラが++t ;またはt++ ;コードを処理するための関数を検索するときに考慮されます。

class T
{
    // etc.
} ;


T & operator++(T & p_oRight) // ++A
{
   // Do increment of p_oRight value
   return p_oRight ;
}

T operator++(T & p_oRight, int) // A++
{
   T oCopy ;
   // Copy p_oRight into oCopy
   // Do increment of p_oRight value
   return oCopy ;
}

C++の観点(C++コンパイラの観点を含む)から、これらの非メンバー関数はTのインターフェイスの一部であることを覚えておくことが重要です(同じ名前空間にある限り)。

非メンバー関数表記法には、2つの潜在的な利点があります。

  • それらをTのフレンドにせずにコーディングできた場合、Tのカプセル化を増やしました。
  • コードを所有していないクラスや構造にもこれを適用できます。これは、宣言を変更せずにオブジェクトのインターフェイスを強化する非侵入的な方法です。
16
paercebal

次のように宣言します。

class A
{
public:
    A& operator++();    //Prefix (++a)
    A operator++(int); //Postfix (a++)

};

適切に実装する-誰もが知っていることを台無しにしないでください(増分してから使用してから、使用してから増分)。

1
Kate Gregory

遅れていることはわかっていますが、同じ問題があり、より簡単な解決策を見つけました。誤解しないでください、これは同じ最上位ソリューション(Martin Yorkによる投稿)と同じソリューションです。 bitより単純です。ちょっとだけ。ここにあります:

class Number
{
        public:

              /*prefix*/  
        Number& operator++ ()
        {
            /*Do stuff */
            return *this;
        }

            /*postfix*/
        Number& operator++ (int) 
        {
            ++(*this); //using the prefix operator from before
            return *this;
        }
};

上記のソリューションは、postfixメソッドで一時オブジェクトを使用しないため、少し単純です。

0
X. Mora