9

来自http://www.learncpp.com/cpp-tutorial/142-function-template-instances/

class Cents
{
private:
    int m_nCents;
public:
    Cents(int nCents)
        : m_nCents(nCents)
    {
    }

    friend bool operator>(Cents &c1, Cents&c2)  // <--- why friend?
    {
        return (c1.m_nCents > c2.m_nCents) ? true: false;
    }
};

我们也可以像这样实现它:

class Cents
{
private:
    int m_nCents;
public:
    Cents(int nCents)
        : m_nCents(nCents)
    {
    }

    bool operator> (Cents& c2)  // <---
    {
        return (this->m_nCents > c2.m_nCents) ? true: false;
    }
};

使用第二种实现有什么缺点吗?

4

4 回答 4

14

假设您使用 const 引用作为参数,第一个实现可以在这样的条件下使用:bool b = 42 > c;这将在第二个实现中提供编译器错误。Cent这将使用整数自动创建一个对象42(因为构造函数未定义为explicit),然后使用该friend函数进行比较。请参阅此常见问题解答中的第 7 点

于 2012-02-28T05:49:48.727 回答
0

第一个定义为Class Member重载运算符,第二个是Nonmember重载运算符。当Nonmember函数访问私有成员 private: int m_nCents;时, friend应该添加。即使我改成public:int m_nCents;,它也不起作用。friend似乎是一个规则,不是因为成员访问限制。但是您可以将非成员运算符移出类主体并访问公共成员变量。有更好的主意吗?我感到困惑。我认为所有非成员运算符(与操作数具有相同的参数号,不能作为成员函数调用)必须friend在类主体中声明。

>是一个二元运算符,每个操作数有两个参数。您已经发现 Class Member 重载运算符>只有一个显式参数和一个隐式this参数。非会员操作员必须有两个。

class Cents{
  private:
     int m_nCents;
  public:
  Cents(int nCents)
     : m_nCents(nCents)
   {
   }

   friend bool operator>(Cents &c1, Cents&c2); //Nomember 

   bool operator<(Cents &c1); //class member
};

bool operator>(Cents &c1, Cents&c2)  // <--- why friend?
{
   //cout << "in >"  << endl;
   return (c1.m_nCents > c2.m_nCents) ? true: false;
}

bool Cents::operator<(Cents &c1)
{
    //cout << "in <"  << endl;
    return (this->m_nCents < c1.m_nCents) ? true: false;
}

int main(){
 //nomember
 //if(poor.operator>(rich))  //compiler error 
 if(poor > rich){
     cout << "oh yeal!" << endl;
 }
 else
 {
     cout << "oh no!" << endl;
 }

 //member
 //if(poor.operator<(rich)) //can call this way
 if(poor.operator<(rich)){
     cout << "oh yeal!" << endl;
 }
 else
 {
     cout << "oh no!" << endl;
 }

}

我将实现移出类主体。现在你可以看到类成员运算符有一个Cents::限定符,就像成员函数一样。

于 2012-02-28T06:15:37.603 回答
-1

一般来说,我认为大多数实际示例没有太大区别。

我更喜欢与class直接关联的第二个选项。此外,以下语法更合适:

bool operator> (const Cents& c2) const
{         //    ^^^^^            ^^^^^
  return (this->m_nCents > c2.m_nCents); // simple
}
于 2012-02-28T05:51:24.953 回答
-2

There's no reason to tag a public method with friend. Friend functions are useful for unrelated classes accessing private or protected members.

That said, you could just drop friend from the first implementation and it'll work fine.

于 2012-02-28T05:55:09.407 回答