运算符重载: 成员函数还是非成员函数?

我读到声明为成员函数的重载操作符是 不对称,因为它只能有一个参数,而自动传递的另一个参数是 this指针。所以没有标准来比较它们。另一方面,声明为 friend的重载操作符是 对称的,因为我们传递了两个相同类型的参数,因此可以比较它们。

我的问题是,当我仍然可以比较指针的左值和引用,为什么朋友是首选?(使用非对称版本得到的结果与对称版本相同) 为什么 STL 算法只使用对称版本?

110066 次浏览

friend操作符重载和成员函数操作符重载之间没有必要区别,因为它是 全球性的操作符重载和成员函数操作符重载之间的区别。

选择 全球性的运算符重载的一个原因是,如果您希望允许类类型出现在二进制运算符的 手边的表达式。例如:

Foo f = 100;
int x = 10;
cout << x + f;

对象的全局运算符重载时,此方法才有效

Foo 运算符 + (int x,const Foo & f) ;

注意,全局运算符重载不一定需要是 friend函数。只有在需要访问 Foo的私有成员时才需要这样做,但情况并非总是如此。

无论如何,如果 Foo只有一个成员函数运算符重载,比如:

class Foo
{
...
Foo operator + (int x);
...
};

... 那么我们只能有一个表达式,其中一个 Foo实例出现在加运算符的 左边上。

如果您将运算符重载的函数定义为成员函数,那么编译器将 s1 + s2等表达式转换为 s1.operator+(s2)。这就是成员函数的工作方式!

但是如果第一个操作数不是一个类呢?所以你不能这样写。但是,您可以为诸如 s1 + 10.0之类的表达式编写运算符重载成员函数。

为了解决这个 点餐问题,我们将操作符重载函数定义为 friend IF,它需要访问 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
}

阅读以下内容:
操作数排序的一个小问题
非成员函数如何改进封装