我读到声明为成员函数的重载操作符是 不对称,因为它只能有一个参数,而自动传递的另一个参数是 this指针。所以没有标准来比较它们。另一方面,声明为 friend的重载操作符是 对称的,因为我们传递了两个相同类型的参数,因此可以比较它们。
this
friend
我的问题是,当我仍然可以比较指针的左值和引用,为什么朋友是首选?(使用非对称版本得到的结果与对称版本相同) 为什么 STL 算法只使用对称版本?
friend操作符重载和成员函数操作符重载之间没有必要区别,因为它是 全球性的操作符重载和成员函数操作符重载之间的区别。
选择 全球性的运算符重载的一个原因是,如果您希望允许类类型出现在二进制运算符的 对手边的表达式。例如:
Foo f = 100; int x = 10; cout << x + f;
对象的全局运算符重载时,此方法才有效
Foo 运算符 + (int x,const Foo & f) ;
注意,全局运算符重载不一定需要是 friend函数。只有在需要访问 Foo的私有成员时才需要这样做,但情况并非总是如此。
Foo
无论如何,如果 Foo只有一个成员函数运算符重载,比如:
class Foo { ... Foo operator + (int x); ... };
... 那么我们只能有一个表达式,其中一个 Foo实例出现在加运算符的 左边上。
如果您将运算符重载的函数定义为成员函数,那么编译器将 s1 + s2等表达式转换为 s1.operator+(s2)。这就是成员函数的工作方式!
s1 + s2
s1.operator+(s2)
但是如果第一个操作数不是一个类呢?所以你不能这样写。但是,您可以为诸如 s1 + 10.0之类的表达式编写运算符重载成员函数。
s1 + 10.0
为了解决这个 点餐问题,我们将操作符重载函数定义为 friend IF,它需要访问 private成员。否则就简单地把它的 非朋友非会员功能封装成 改进!
private
class Sample { public: Sample operator + (const Sample& op2); //works with s1 + s2 Sample operator + (double op2); //works with s1 + 10.0 //Make it `friend` only when it needs to access private members. //Otherwise simply make it **non-friend non-member** function. friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2 }
阅读以下内容: 操作数排序的一个小问题 非成员函数如何改进封装