Effective C++勉強メモ: Item 24 右辺左辺どちらでも型変換が必要な可能性があるオペレータはNon-Member関数
ごくたまに暗黙の型変換が役にたつ時がある。特定の数字を表現するクラスを定義する時などである。
class Rational { private: const int numerator, denominator; public: Rational(int numerator = 0, int denominator = 1); const Rational operator*(const Rational& rhs) const; } Rational a(1, 2); Rational b(3, 4); Rational x = a * b; Rational y = a * 2; Rational z = 2 * b
有理数を表すRational
クラスが上記のように定義されていた場合、Rational * Rational
は問題なく実行できる。
Rational * Int
もRational
のコンストラクタが暗黙的にInt
をnumerator
として受け取って型変換するのでoperator*
が適用できる。
しかしInt * Rational
はコンパイルエラーだ。なぜかというとRational
クラス内で定義されていたoperator*
はRational
が演算子の左辺にある場合にのみ適用されるからである。そしてInt
にはRational
とのoperator*
は定義されていない。
class Rational { private: const int numerator, denominator; public: Rational(int numerator = 0, int denominator = 1); } const Rational operator*(const Rational& lhs, const Rational& rhs) { ... };
とRational
型同士の掛け算をnon-memberなoperator*
として定義すれば左辺がInt
であっても暗黙の型変換が行われる。
ついでにいうとRational
クラスにnumerator/denominator
のgetter
が定義されていればFriend
関数である必要もない。なるべくそのような設計になるよう心がけるべき。
Whenever you can avoid friend functions, you should, because, much as in real life, friends are often more trouble than they're worth - Scott Meyers
なんだかサイモン・アンド・ガーファンクルっぽいことを言っている・・・