来自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;
}
};
使用第二种实现是否有任何缺点?
答案 0 :(得分:11)
假设您使用const引用作为参数,第一个实现可以在这样的条件下使用:bool b = 42 > c;
这将在第二个实现中提供编译器错误。这将使用整数Cent
自动创建42
对象(因为构造函数未定义为explicit
),然后使用friend
函数进行比较。请参阅此FAQ
答案 1 :(得分:0)
第一个定义为类成员重载运算符,第二个是非成员重载运算符。当非成员函数访问私有成员时
应该添加private:
int m_nCents;
,friend
。即使我更改为public:int m_nCents;
,它也不起作用。friend
似乎是一个规则,而不是因为成员访问限制。但是您可以将Nonmember运算符移出类主体并访问公共成员变量。有什么好主意吗?我感到困惑。我认为 ALL 非成员运算符(与操作数具有相同的参数号,不能作为成员函数调用)必须在类体中声明为friend
。
>
是一个二元运算符,每个操作数都有两个参数。您发现类成员重载运算符>
只有一个显式参数和一个隐式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::
限定符,就像成员函数一样。
答案 2 :(得分:-1)
我认为大多数实际例子一般没有太大区别。
我更喜欢第二个选项,它直接与class
相关联。而且,以下语法更合适:
bool operator> (const Cents& c2) const
{ // ^^^^^ ^^^^^
return (this->m_nCents > c2.m_nCents); // simple
}
答案 3 :(得分:-2)
没有理由与朋友标记公共方法。朋友函数对访问私有或受保护成员的无关类很有用。
那就是说,你可以放弃第一个实现的朋友,它会正常工作。