运算符 == 或 << when should i use it?

问题描述 投票:0回答:5

我觉得我对

friend
关键字的理解有点漏洞。

我有课,

presentation
。我在代码中将它用于两个变量,
present1
present2
,我将其与
==
进行比较:

if(present1==present2)

这是我如何定义运算符

==
(在
class presentation
中):

bool operator==(const presentation& p) const;

但是,我被告知使用

friend
并在课堂外定义它会更好:

friend bool operator==(presentation&, presentation&);

为什么?两者有什么区别?

c++ operator-overloading friend
5个回答
24
投票

您的解决方案有效,但它不如

friend
方法强大。

当一个类将一个函数或另一个类声明为

friend
时,这意味着友元函数或类可以访问声明类的私有成员和受保护成员。就好像声明的实体是声明类的成员一样。

如果将

operator==()
定义为成员函数,那么就像
friend
的情况一样,成员函数可以完全访问类的成员。但因为它是一个成员函数,所以它指定单个参数,因为第一个参数隐含为
this
:类型为
presentation
(或其后代)的对象。但是,如果您将函数定义为非成员,那么您可以指定两个参数,这将使您可以灵活地比较可以使用同一函数转换为
presentation
的任意两种类型。

例如:

class presentation {
    friend bool operator==(const presentation&, const presentation&);
    // ...
};

class Foo : public presentation { /* ... */ };
class Bar : public presentation { /* ... */ };

bool operator==(const presentation& p1, const presentation& p2)
{
    // ...
}

bool func(const Foo& f, const Bar& b, const presentation& p)
{
    return (f == b || f == p );
}

最后,这提出了一个问题“为什么要声明

friend
?”。如果
operator==()
函数不需要访问
presentation
的私有成员,那么实际上最好的解决方案是使其成为非成员、非友元函数。换句话说,不要授予不需要的函数访问权限。


4
投票

在第一种情况下,您的函数

operator==
是非静态类成员。因此它可以访问私有和受保护的成员变量。

在第二种情况下,运算符是外部声明的,因此应该将其定义为类的友元来访问这些成员变量。


2
投票

作为方法实现的运算符,只能被调用,如果左侧表达式是类的变量(或对象的引用),则定义该运算符。

如果是

operator==
,通常您会对比较同一类的两个对象感兴趣。实施,作为一种方法可以解决您的问题。

但是想象一下,您编写了一个字符串类,并且想要一个运算符在这种情况下工作:

const char *s1 = ...
MyString s2 = ...
if(s1 == s2){...

要使表达式

s1 == s2
合法,您必须将
opetator==
定义为
MyString
类的外部函数。

bool operator==(const char *, const MyString&);

如果操作员需要访问您班级的私有成员,则它必须是您班级的好友。

对于适用于流的运算符

<<
>>
,您定义一个运算符,其左操作数是流实例,右操作数是您的类,因此它们不能是您类的方法。就像上面的例子一样,如果需要访问私有成员,它们必须是你的班级和朋友的外部函数。


1
投票

我喜欢伯努瓦的回答(但我不能投票赞成),但我认为举一个例子来澄清它不会有什么坏处。这是我的一些货币代码(假设其他所有内容都放置正确):

// header file
friend bool operator ==(const Money, const Money); // are the two equal?

// source file
bool operator ==(const Money a1, const Money a2)
{
    return a1.all_cents == a2.all_cents;
}

希望有帮助。


0
投票

在这里看看这个重复的内容:should-operator-be-implemented-as-a-friend-or-as-a-member-function

需要指出的是,这个链接的问题是关于

<<
>>
,它们应该作为友元实现,因为这两个操作数是不同的类型。

就您而言,将其作为课程的一部分来实现是有意义的。友元技术用于(并且很有用)用于使用多种类型的情况,并且通常不适用于

==
!=

© www.soinside.com 2019 - 2024. All rights reserved.