C++で前置・後置インクリメント/デクリメント演算子をオーバーロードする

オーバーロードのやり方自体は他の演算子と同じだけど、前置と後置でどのように定義を書き分ければいいのか知らなかったので調べてみた。

前置と後置の違い

  • 前置インクリメント/デクリメント
    • 戻り値は*thisへのリファレンスにする
      • ++(++t)のように、戻り値を左辺値として扱えるようにする
  • 後置インクリメント/デクリメント
    • 関数定義の際に引数にダミーのintを与える
    • 戻り値は++/--前の*thisのコピーにする

テスト用に書いたサンプルコード

こんな感じで定義を書けばOK。

#include <iostream>
using namespace std;

class test {
public:
    int n;

    // コンストラクタ
    test(int n = 0) : n(n) {}
    // 前置インクリメントのオーバーロード
    test& operator ++() {
        this->n++;
        return *this;
    }
    // 後置インクリメントのオーバーロード
    test operator ++(int) {  // 引数にintと書くと後置扱いになる
        test t = *this;
        this->n++;
        return t;
    }
};

// cout << tで値を出力できるようにする
ostream& operator <<(ostream &o, const test &t) {
    o << t.n;
    return o;
}

int main() {
    test t = 10;

    cout << "t  : " << t << endl;
    cout << "++t: " << ++t << endl;
    cout << "t++: " << t++ << endl;
    cout << "t  : " << t << endl;
    return 0;
}

出力はこちら。

t  : 10
++t: 11
t++: 11
t  : 12

デクリメントの場合も同じ要領でオペレータオーバーロードできる。

参考

オペレータ(演算子)のオーバーロード - C++マニアック
http://homepage2.nifty.com/well/Operator.html

どうでもいいけど

クラス定義の}の後にセミコロンを書き忘れないように気をつけようね!