ikautak.log

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

More Effective C++ 項目21 暗黙的な型変換を避けるためのオーバーロード

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

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

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

項目21 暗黙的な型変換を避けるためのオーバーロード

次のコードでは、暗黙の型変換でテンポラリオブジェクトが作られる。

class UPInt {
public:
  UPInt();
  UPInt(int value);
  ...
};

const UPInt operator+(const UPInt& a, const UPInt& b);
UPInt upi1, upi2;
...

UPInt upi3 = upi1 + 10;  // 暗黙の型変換
upi3 = 10 + upi2;  // 暗黙の型変換

変換のためにテンポラリオブジェクトが作られるのはコストがかかるため、UPIntとintを加算したいときは、operator+を複数定義すると良い。

const UPInt operator+(const UPInt& a, int b);  // UPIntとintを加算
const UPInt operator+(int a, const UPInt& b);  // intとUPIntを加算

UPInt upi1, upi2;
...
UPInt upi3 = upi1 + upi2;  // OK。テンポラリなし

upi3 = upi1 + 10;  // OK。テンポラリなし
upi3 = 10 + upi2;  // OK。テンポラリなし

これでテンポラリオブジェクトが作られるのを防げる。
ただし、以下の関数はエラーになる。

const UPInt operator+(int a, int b);

C++ではオーバーロードされた演算子の実引数のうち1つは、必ずユーザ定義型でなければならない。 両方intにしたoperator+はオーバーロードできない。

まとめ

テンポラリオブジェクトを避けるために演算子のオーバーロードは有効。
operatorに限らず、char*とstringの両方を許可する文字列ライブラリや、intとdoubleを許可するcomplexクラスなどにもオーバーロードは有効である。
ただし、オーバーロードは80-20規則(項目16)を念頭に置き、節操もなく多用するのは良くない。