从previous question我想继续问为什么“朋友”的形式除了在C++操作符重载的优先C++操作符覆盖 - 为什么它是朋友的首选?
总结:
的加法运算符覆盖有两种方法可以做到这一点:
int operator+(Object& e);
friend int operator+(Object& left, Object& right);
为什么第二个(朋友)表单是首选?有什么优势?
从previous question我想继续问为什么“朋友”的形式除了在C++操作符重载的优先C++操作符覆盖 - 为什么它是朋友的首选?
总结:
的加法运算符覆盖有两种方法可以做到这一点:
int operator+(Object& e);
friend int operator+(Object& left, Object& right);
为什么第二个(朋友)表单是首选?有什么优势?
首选非成员版本(朋友或其他),因为它可以支持操作符左侧和右侧的隐式转换。
给定一个类型,它是隐式转换为对象:
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
版本(例如您的帖子演示的情况)。
此实现突出的事实,操作确实是对称的:它不是一个“对象这”,增加了Object e
本身 - 更确切地说,这是一个加lhs
和rhs
。
在情况下,当操作非对称的 - 例如,当你添加一个int
一个迭代器,你应该更喜欢实现运营商的第一种方式,即
Object& operator+(int& offset);
可能更好地引用相关位从最后一个问题开始,所以人们不必点击它(也可以在问题消失的情况下) – nneonneo