运营商中的朋友==或"我应该何时使用它?

Nad*_*dav 14 c++ operator-overloading friend

我觉得我对friend关键字的理解有点漏洞.

我有一节课presentation.我在我的代码中使用它来获取两个变量,present1并且present2我将其与之比较==:

if(present1==present2)
Run Code Online (Sandbox Code Playgroud)

这是我如何定义运算符==(in class presentation):

bool operator==(const presentation& p) const;
Run Code Online (Sandbox Code Playgroud)

但是,我被告知friend在课堂外使用和定义它更好:

friend bool operator==(presentation&, presentation&);
Run Code Online (Sandbox Code Playgroud)

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

wil*_*ell 14

您的解决方案有效,但它不如该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 );
}
Run Code Online (Sandbox Code Playgroud)

最后,这引出了"为什么friend声明?"的问题.如果operator==()函数不需要访问私有成员presentation那么确实最好的解决方案是使其成为非成员,非朋友的功能.换句话说,不要给出不需要的功能访问权限.


Ben*_*oit 4

在第一种情况下,你的函数operator==是非静态类成员。因此它可以访问私有和受保护的成员变量。

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

  • 好的,但为什么我想要它外部声明呢?即使该声明在类中列为公开的,它仍然在外部吗?第一个也可以吗? (2认同)