ikautak.log

C/C++, Python, CUDA, Android, Linux kernel, Network, etc.

More Effective C++ 項目6 インクリメントとデクリメントの演算子で前置形式と後置形式を区別する

新訂版 More Effective C++ (AddisonーWesley professional co)

新訂版 More Effective C++ (AddisonーWesley professional co)

  • 作者: スコット・メイヤーズ,安村通晃,伊賀聡一郎,飯田朱美,永田周一
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2007/06/29
  • メディア: 単行本(ソフトカバー)
  • 購入: 8人 クリック: 129回
  • この商品を含むブログ (43件) を見る

項目6 インクリメントとデクリメントの演算子で前置形式と後置形式を区別する

区別できるなんて知らなかったが、前置は引数を取らず、後置はintを取るように書き、そこにコンパイラが0を渡すらしい。

class UPInt {
public:
    UPInt& operator++();  // 前置++
    const UPInt operator++(int);  // 後置++

    UPInt& operator--();  // 前置--
    const UPInt operator--(int);  // 後置--

    ...
};

引数なしが前置、intを受け取るのが後置で、コンパイラが0を渡す。

UPInt i;

++i;  // i.operator++()
i++;  // i.operator++(0)

--i;  // i.operator--()
i--;  // i.operator--(0)


戻り値も違って、前置は参照を返すが、後置はconstオブジェクトを返す。

// 前置:インクリメントして返す
UPInt& UPInt::operator++() {
   *this += 1;
   return *this;
}

// 後置:値を返して、インクリメント
const UPInt UPInt::operator++(int) {
    UPInt oldValue = *this;
    ++(*this);

    return oldValue; // インクリメント前の値を返すから、コピーしたオブジェクトを返す。
}

戻り値にconstを付けるのは

i++++;

の記述を禁止するためらしい。int型では禁止されているので、自作クラスも禁止するべきとのこと。
UPIntクラスの場合、i.operator++(0).operator++(0)と同じなので、constを付けると二つ目でエラーとなる。


後置はテンポラリオブジェクトが必要になるので、効率が悪い。ユーザ定義型を用意する場合は可能なかぎり前置を使う。
前置と後置の振る舞いを同じにするためには、後置の実装に前置を使うとよい。

まとめ
インクリメント・デクリメントでは適切なデータ型(前置は参照、後置はconstオブジェクト)を返す。 後置演算子は、前置を用いて実装するべき。