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

发布于 2024-10-10 23:11:00 字数 237 浏览 8 评论 0原文

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

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

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. 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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巴黎盛开的樱花 2024-10-17 23:11:00

如果将运算符重载函数定义为成员函数,则编译器会将 s1 + s2 等表达式转换为 s1.operator+(s2)这意味着,运算符重载的成员函数在第一个操作数上被调用。这就是成员函数的工作原理!

但是如果第一个操作数不是类怎么办? 如果我们想要重载一个运算符,其中第一个操作数不是类类型,而是double,则会出现一个主要问题。所以你不能像这样写10.0 + s2 。但是,您可以为 s1 + 10.0 等表达式编写运算符重载成员函数。

为了解决这个排序问题,我们将运算符重载函数定义为friend(如果它需要访问private成员)。 仅当需要访问私有成员时才将其设为好友否则只需将其设为非好友非成员功能即可改进< /em> 封装!

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
}

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

If you define your operator overloaded function as member function, then the compiler translates expressions like s1 + s2 into 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. So you cannot write like this 10.0 + s2. However, you can write operator overloaded member function for expressions like s1 + 10.0.

To solve this ordering problem, we define operator overloaded function as friend IF it needs to access private members. Make it friend ONLY when it needs to access private members. 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

注定孤独终老 2024-10-17 23:11:00

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 实例出现在 上的表达式加号运算符左侧。

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.

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);

Note that the global operator overload doesn't necessarily need to be a friend function. This is only necessary if it needs access to private members of Foo, but that is not always the case.

Regardless, if Foo only had a member function operator overload, like:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文