继续上一个问题,我想问一下为什么首选 C++ 运算符覆盖中的“朋友”形式的加法
总结一下:
对于加法运算符覆盖,有两种方法可以做到:
int operator+(Object& e);
friend int operator+(Object& left, Object& right);
为什么首选第二种(朋友)形式?有什么优势?
非成员版本(朋友或其他)是首选,因为它可以支持运算符左侧和右侧的隐式转换。
给定一个可隐式转换为 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
调用Object
。
该规则不是通用的: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);