运算符 == 或 << 中的朋友我什么时候应该使用它?
我觉得我对 friend
关键字的理解有点漏洞。
我有一堂课,演示
。我在代码中将它用于两个变量 present1
和 present2
,我将它们与 ==
进行比较:
if(present1==present2)
以下是我定义运算符 ==
(在类演示
中):
bool operator==(const presentation& p) const;
但是,我被告知使用friend
并在类之外定义它更好:
friend bool operator==(presentation&, presentation&);
为什么?两者有什么区别?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在第一种情况下,您的函数
operator==
是非静态类成员。因此它可以访问私有和受保护的成员变量。在第二种情况下,运算符是外部声明的,因此应该将其定义为类的友元来访问这些成员变量。
In the first case, your function
operator==
is a nonstatic class member. It has therefore access to private and protected member variables.In the second case, the operator is externally declared, therefore it should be defined as a friend of the class to access those member variables.
实现为方法的运算符只能在左侧表达式是定义该运算符的类的变量(或对象的引用)时被调用。
对于
operator==
,通常您有兴趣比较同一类的两个对象。实施作为一种方法可以解决您的问题。然而,想象一下,您编写了一个字符串类,并且想要一个运算符在这种情况下工作:
要使表达式
s1 == s2
合法,您必须定义一个operator==< /code> 作为
MyString
类的外部函数。如果操作员需要访问您班级的私有成员,那么它必须是您班级的友元。
对于适用于流的运算符
<<
和>>
,您可以定义一个运算符,其左操作数是流实例,右操作数是你的类,所以它们不能是你类的方法。就像上面的例子一样,如果需要访问私有成员,它们必须是你的类和朋友的外部函数。An operator implemented as a method, can only be called, if the left hand side expression is a variable (or a reference to the object) of the class, the operator is defined for.
In case of an
operator==
usually you are interested in comparing two objects of the same class. Implementation, as a method solves your problem here.Imagine however, that you write a string class and you want an operator, to work in this scenario:
To make the expression
s1 == s2
legal, you have to define anopetator==
as a function external toMyString
class.If the operator needs an access to the private members if your class, it has to be a friend of your class.
In case of operators
<<
and>>
, that work on streams, you define an operator, whose left operand is a stream instance and the right one is your class, so they can't be methods of your class. Like in the example above, they have to be functions external to your class and friends, if the access to private members is required.我喜欢伯努瓦的回答(但我不能投票赞成),但我认为举一个例子来澄清它不会有什么坏处。这是我的一些货币代码(假设其他所有内容都放置正确):
希望有所帮助。
I like Benoit's answer (but I can't vote it up), but I figure an example wouldn't hurt to clarify it. Here's some Money code I have (assume everything else is placed right):
Hope that helps.
在这里看看这个重复的内容: should-operator-be-implemented-as-a-friend-or-as-a-member-function
需要指出的是,这个链接的问题是关于
<<
和>>
应该作为友元实现,因为这两个操作数是不同的类型。就您而言,将其作为课程的一部分来实现是有意义的。友元技术用于(并且很有用)用于使用多种类型的情况,并且通常不适用于
==
和!=
。Take a look at this sorta duplicate here: should-operator-be-implemented-as-a-friend-or-as-a-member-function
What is important to point out, this linked question is about
<<
and>>
which should be implemented as friends since the two operand are different types.In your case it makes sense to implement it as part of the class. The friend technique is used (and useful) for cases where more than one type is used and often does not apply to
==
and!=
.您的解决方案有效,但它不如
friend
方法强大。当一个类将一个函数或另一个类声明为
friend
时,这意味着该友元函数或类可以访问声明类的私有成员和受保护成员。就好像声明的实体是声明类的成员一样。如果将
operator==()
定义为成员函数,那么就像friend
情况一样,成员函数可以完全访问类的成员。但因为它是一个成员函数,所以它指定一个参数,因为第一个参数隐含为this
:一个presentation
类型的对象(或其后代)。但是,如果您将该函数定义为非成员,则可以指定这两个参数,这样您就可以灵活地比较可以使用同一函数转换为presentation
的任何两种类型。例如:
最后,这提出了一个问题“为什么要声明
friend
?”。如果operator==()
函数不需要访问presentation
的私有成员,那么实际上最好的解决方案是使其成为非成员、非友元函数。换句话说,不要授予不需要的函数访问权限。Your solution works, but it's less powerful than the
friend
approach.When a class declares a function or another class as
friend
it means that friend function or class have access to the declaring class' privates and protected members. It's as if the declared entity was a member of the declaring class.If you define
operator==()
as a member function then just like with thefriend
case the member function has full access to the class' members. But because it is a member function it specifies a single parameter, as the first parameter is implied to bethis
: an object of typepresentation
(or a descendent thereof). If, however, you define the function as a non-member then you can specify both parameters, and this will give you the flexibility of comparing any two types that can cast into apresentation
using that same function.For example:
Lastly, this raises the question "why the
friend
declaration?". If theoperator==()
function does not need access to private members ofpresentation
then indeed the best solution is to make it a non-member, non-friend function. In other words, don't give a function access privileges which is doesn't need.