简体   繁体   English

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

[英]Operator overloading : member function vs. non-member function?

I read that an overloaded operator declared as member function is asymmetric because it can have only one parameter and the other parameter passed automatically is the this pointer. 我读到声明为成员函数的重载运算符是不对称的,因为它只能有一个参数,而另一个自动传递的参数是this指针。 So no standard exists to compare them. 因此,没有标准可以比较它们。 On the other hand, overloaded operator declared as a friend is symmetric because we pass two arguments of the same type and hence, they can be compared. 另一方面,声明为friend重载运算符是对称的,因为我们传递了相同类型的两个参数,因此可以对其进行比较。

My question is that when i can still compare a pointer's lvalue to a reference, why are friends preferred? 我的问题是,当我仍然可以将指针的左值与引用进行比较时,为什么首选朋友? (using an asymmetric version gives the same results as symmetric) Why do STL algorithms use only symmetric versions? (使用非对称版本可获得与对称相同的结果)为什么STL算法仅使用对称版本?

If you define your operator overloaded function as member function, then the compiler translates expressions like s1 + s2 into s1.operator+(s2) . 如果将运算符重载函数定义为成员函数,则编译器s1.operator+(s2) s1 + s2类的表达式转换为s1.operator+(s2) That means, the operator overloaded member function gets invoked on the first operand. 这意味着,运算符重载的成员函数在第一个操作数上被调用。 That is how member functions work! 这就是成员函数的工作方式!

But what if the first operand is not a class? 但是,如果第一个操作数不是类怎么办? There's a major problem if we want to overload an operator where the first operand is not a class type, rather say double . 如果我们要重载第一个操作数不是类类型的操作符,而要说double ,则会出现一个主要问题。 So you cannot write like this 10.0 + s2 . 所以你不能这样写10.0 + s2 However, you can write operator overloaded member function for expressions like s1 + 10.0 . 但是,您可以为s1 + 10.0类的表达式编写运算符重载成员函数。

To solve this ordering problem, we define operator overloaded function as friend IF it needs to access private members. 为了解决此排序问题,如果需要访问private成员,我们将运算符重载函数定义为friend Make it friend ONLY when it needs to access private members. 仅在需要访问私有成员时使其成为friend Otherwise simply make it non-friend non-member function to improve encapsulation! 否则,只需使其成为非朋友非成员函数即可改善封装!

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
}

Read these : 阅读这些:
A slight problem of ordering in operands 操作数排序的一个小问题
How Non-Member Functions Improve Encapsulation 非成员函数如何改善封装

It's not necessarily a distinction between friend operator overloads and member function operator overloads as it is between global operator overloads and member function operator overloads. 这并不一定区分friend运算符重载和成员函数运算符重载,因为它是全球性的操作符重载和成员函数运算符重载之间。

One reason to prefer a global operator overload is if you want to allow expressions where the class type appears on the right hand side of a binary operator. 一个理由,更喜欢一个全球性的运算符重载是,如果你想允许式,其类类型的二元运算符的右侧出现。 For example: 例如:

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

This only works if there is a global operator overload for 这仅在以下情况下有效:

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

Note that the global operator overload doesn't necessarily need to be a friend function. 需要注意的是,全球运算符重载并不一定需要是一个friend的功能。 This is only necessary if it needs access to private members of Foo , but that is not always the case. 这是只需要如果需要访问的私有成员Foo ,但事实并非总是如此。

Regardless, if Foo only had a member function operator overload, like: 无论如何,如果Foo只有一个成员函数运算符重载,如:

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

...then we would only be able to have expressions where a Foo instance appears on the left of the plus operator. ......那么我们只能够在那里一个有表情Foo实例左边的加号的出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM