5

继续上一个问题,我想问一下为什么首选 C++ 运算符覆盖中的“朋友”形式的加法

总结一下:

对于加法运算符覆盖,有两种方法可以做到:

int operator+(Object& e);
friend int operator+(Object& left, Object& right);

为什么首选第二种(朋友)形式?有什么优势?

4

2 回答 2

5

非成员版本(朋友或其他)是首选,因为它可以支持运算符左侧和右侧的隐式转换。

给定一个可隐式转换为 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 & )使用通过转换wObject. 所以结果和写一样o + w.operator Object()

但是在表达式w + o中,编译器会寻找Widget::operator+(不存在的)或非成员operator+( Widget, Object )。后者可以通过转换为上述来w调用Object

于 2012-10-07T01:03:28.590 回答
2

该规则不是通用的:friend当您实现一个逻辑对称操作时,该版本是首选的,该操作采用相同类型的两个参数,例如您的帖子演示的情况。

This implementation underscores the fact that the operation is truly symmetric: it's not a 'Object this' that adds Object e to itself - rather, that's an addition of lhs and rhs.

In situations when the operation is non-symmetric - for example, when you add an int to an iterator, you should prefer the first way of implementing operators, namely

Object& operator+(int& offset);
于 2012-10-07T01:17:22.397 回答