私はEffective C ++を読んでいて、これに出くわしました:
class Rational { ... };
const Rational operator*(const Rational& lhs, const Rational& rhs);
この演算子はオーバーロードしていますか? はいの場合、なぜ奇妙な形になっているのですか?
前もって感謝します。
私はEffective C ++を読んでいて、これに出くわしました:
class Rational { ... };
const Rational operator*(const Rational& lhs, const Rational& rhs);
この演算子はオーバーロードしていますか? はいの場合、なぜ奇妙な形になっているのですか?
前もって感謝します。
この演算子はオーバーロードしていますか? はいの場合、なぜ奇妙な形になっているのですか?
はい。フォームは「変」ではありません。これは、2 つの有理数を掛け合わせる 1 つの形式にすぎません。
演算子は、メンバー関数または非メンバー関数としてオーバーロードできます。非メンバー関数 (このような) を使用する主な利点は、Rational
クラスのプライベートな状態にアクセスしたり、左側のオペランドを変更したりしていないことを明確にしていることです (これは により明確ですconst
) .
メンバー関数のバージョンは、左側のオペランド ( this
) を変更する場合、またはクラスの一部である必要がある型内のプライベート変数にアクセスする必要がある場合にのみ必要です。それ以外の場合、プライベート状態にアクセスするには、これをフレンド関数として宣言する必要があります。
それは一般的であり、良い考えです。通常、他の演算子に関して演算子を実装し、メンバー関数が多すぎないようにします。あなたの場合:
class Rational
{
public:
// member function for += with access to the internals
Rational& operator+=( const Rational& rhs );
};
// free function for + using public copy-ctor and +=,
// therefore no need to access internals of Rational
// and hence no need to be a member or friend of Rational!
Rational operator+( const Rational& lhs, const Rational& rhs )
{
Rational result( lhs );
result += rhs;
return result;
}
2 番目の方法は一般的なパターンに従うため、Boost.Operatorsや my df.operatorsなど、それを支援するライブラリがあります。これらのライブラリの助けを借りて、必要なのは
class Rational : df::commutative_addable< Rational >
{
public:
// member function for += with access to the internals
Rational& operator+=( const Rational& rhs );
};
+ を自動的に生成します。