friend in operator == or << when should i use it?

Nadav picture Nadav · Oct 3, 2010 · Viewed 9.2k times · Source

I feel I have a bit of a hole in my understanding of the friend keyword.

I have a class, presentation. I use it in my code for two variables, present1 and present2, which I compare with ==:

if(present1==present2)

Here's how I defined the operator == (in class presentation):

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

However, I was told that using friend and defining it outside of the class is better:

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

Why? What's the difference between the two?

Answer

wilhelmtell picture wilhelmtell · Oct 3, 2010

Your solution works, but it's less powerful than the friend approach.

When a class declares a function or another class as friend it means that friend function or class have access to the declaring class' privates and protected members. It's as if the declared entity was a member of the declaring class.

If you define operator==() as a member function then just like with the friend case the member function has full access to the class' members. But because it is a member function it specifies a single parameter, as the first parameter is implied to be this: an object of type presentation (or a descendent thereof). If, however, you define the function as a non-member then you can specify both parameters, and this will give you the flexibility of comparing any two types that can cast into a presentation using that same function.

For example:

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

Lastly, this begs the question "why the friend declaration?". If the operator==() function does not need access to private members of presentation then indeed the best solution is to make it a non-member, non-friend function. In other words, don't give a function access privileges which is doesn't need.