Why should we use the friend function to define a comparison operator?

From 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; } }; 

We could also implement it as follows:

 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; } }; 

Is there a drawback to using the second implementation?

+4
source share
4 answers

Assuming that you use constant references as parameters, the first implementation can be used in such conditions: bool b = 42 > c; , which will provide a compiler error in the second implementation. This will automatically create the Cent object using the integer 42 (since the constructor is not defined as explicit ), and then use the friend function to compare. See Point 7 in this FAQ

+11
source

The first is defined as the member class overload operator, the second is the nonmember overload operator. When the Nonmember function accesses the private member private: int m_nCents; , friend must be added. Even I go to public:int m_nCents; , he does not work. friend seems to be the rule, not because of limiting access to membership. But you can move the Nonmember statement from the class of the class and access the public member variable. Any better idea? I feel embarrassed. I think that the ALL Nonmember operator (has the same parameter number with the operand and cannot be called as a member function) should be declared as friend in the body class.

> is a binary operator that has two parameters for each operand. You have found that the member > class overload operator has only an explicit parameter, one and an implicit this parameter. An operator without a member must have two.

 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; } } 

I am moving implementations from the body of the class. Now you can see that the member operator of the class has the qualifier Cents:: as a member function.

0
source

I do not see much difference in most practical examples in general.

I prefer the second option, which is directly related to the class . Moreover, the following syntax is more suitable:

 bool operator> (const Cents& c2) const { // ^^^^^ ^^^^^ return (this->m_nCents > c2.m_nCents); // simple } 
-one
source

There is no reason to tag a public method with a friend. Friend functions are useful for unrelated classes that access private or protected members.

However, you can just drop the friend from the first implementation, and it will work fine.

-2
source

Source: https://habr.com/ru/post/1398752/


All Articles