2012-10-07 32 views
5

previous question我想继续问为什么“朋友”的形式除了在C++操作符重载的优先C++操作符覆盖 - 为什么它是朋友的首选?

总结:

的加法运算符覆盖有两种方法可以做到这一点:

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

为什么第二个(朋友)表单是首选?有什么优势?

+1

可能更好地引用相关位从最后一个问题开始,所以人们不必点击它(也可以在问题消失的情况下) – nneonneo

回答

5

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

给定一个类型,它是隐式转换为对象:

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来调用后者。

+0

我不太了解窗口小部件/对象结构代码,您能否提供一个简单且极其简短的示例? –

2

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

此实现突出的事实,操作确实是对称的:它不是一个“对象这”,增加了Object e本身 - 更确切地说,这是一个加lhsrhs

在情况下,当操作非对称的 - 例如,当你添加一个int一个迭代器,你应该更喜欢实现运营商的第一种方式,即

Object& operator+(int& offset);