前の質問から続けて、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をコンパイラに通知します。WidgetObject
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」ではなく、むしろ、lhsandの追加ですrhs。
演算が非対称の場合 - たとえば、intイテレータに an を追加する場合、演算子を実装する最初の方法を優先する必要があります。
Object& operator+(int& offset);