前の質問から続けて、C++演算子オーバーライドでの「フレンド」形式の加算がなぜ好まれるのかを尋ねたいと思います
要約する:
加算演算子のオーバーライドには、次の2つの方法があります。
int operator+(Object& e);
friend int operator+(Object& left, Object& right);
2番目の(友達)フォームが好まれるのはなぜですか?利点は何ですか?
演算子の左側と右側の両方で暗黙的な変換をサポートできるため、非メンバー バージョン (フレンドまたはその他) が推奨されます。
暗黙的に Object に変換可能な型が与えられた場合:
struct Widget
{
operator Object() const;
};
Widget
のインスタンスが左側にある場合、非メンバー バージョンのみを呼び出すことができます。
Widget w;
Object o;
o + w; // can call Object::operator+( Object & ) since left-hand side is Object
w + o; // can only call operator+( Object &, Object & )
あなたのコメントに応えて:
で変換演算子を定義することにより、 のインスタンスを のインスタンスに自動的に変換できることWidget
をコンパイラに通知します。Widget
Object
Widget w;
Object o = w; // conversion
式o + w
では、コンパイラはObject::operator+( Object & )
に変換することによって生成された引数を使用してw
呼び出しますObject
。したがって、結果は書き込みと同じo + w.operator Object()
です。
しかし、式w + o
では、コンパイラはWidget::operator+
(存在しない) または非メンバーを探しoperator+( Widget, Object )
ます。後者は、上記のようw
に anに変換することで呼び出すことができますObject
。
ルールは普遍的ではありませんfriend
。投稿が示す場合のように、同じ型の 2 つの引数を取る論理的に対称な操作を実装する場合は、バージョンが優先されます。
この実装は、操作が真に対称的であるという事実を強調しています。Object e
それ自体に追加されるのは「Object this」ではなく、むしろ、lhs
andの追加ですrhs
。
演算が非対称の場合 - たとえば、int
イテレータに an を追加する場合、演算子を実装する最初の方法を優先する必要があります。
Object& operator+(int& offset);