Why use "friend" key word when overloading operator<<?

Feb 27, 2012 at 8:33am
I am curious about using friend function...

After reading some books, it is always suggested to use "friend" when overloading operator<<.

Why do we have to do that?

Can't we just make the overloading function be a member of that class?
For example,

ostream& operator<<(ostream& out, const Passenger& pass) {
out<<pass.name<<endl;
return os;
}

Why do we have to let it be a function outside the class which gain access to the class's attribute? What is its pros and cons?

Thank you for your answer :))
Feb 27, 2012 at 8:52am
Because the << operator is not truly a part of the class since it is a universal operator and it will or may need access to protected and private data in the class. Declaring the operator as a friend grants it access.

Last edited on Feb 27, 2012 at 8:55am
Feb 27, 2012 at 9:42am
@jwings - Why don't you just test it both ways.
Write a simple class and make the operator << a class member function, then do it as a friend functions and see what happens and how you would call the different overloads
and the differences are when you do a chained assignment ( a= b = c).
Feb 27, 2012 at 2:09pm
> it is always suggested to use "friend" when overloading operator<<.

That is a terrible suggestion. A friend declaration should only be used if the overloaded operator function needs access to the implementation.

For example, a friend declaration is neither needed nor desirable in this case:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>

struct book
{
    book( const char* title, const char* author )
            : _title(title), _author(author) {}

    const std::string& title() const { return _title ; }
    const std::string& author() const { return _author ; }

    private:
       const std::string _title ;
       const std::string _author ;
};

inline std::ostream& operator<< ( std::ostream& stm, const book& bk )
{ return stm << '{' << bk.title() << " : " << bk.author() << '}' ; }

int main()
{
    book ruminations( "Ruminations on C++", "Koenig&Moo" ) ;
    std::cout << ruminations << '\n' ;
}



Feb 27, 2012 at 3:28pm
Can't we just make the overloading function be a member of that class?
For example,

ostream& operator<<(ostream& out, const Passenger& pass) {
out<<pass.name<<endl;
return os;
}


We cannot because the first operand of a member function is a poiner to object that is this. So in any case this operator function should be global. However we can provide a public interface that can be used inside this operator-function.

For example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class myCllass
{
public:
   myClass( int i = 0 ) : x( i ) {}
   std::ostream & out( std::ostream & os ) const
   {
      return ( os << x );
   }
private:
   int x;
};

std::ostream & operator( std::ostream &os, const myClass &rhs )
{
   return ( rhs.out( os ) );
}


In this case there is no need to declare function operator << as a friend of the class.
Last edited on Feb 27, 2012 at 3:30pm
Feb 27, 2012 at 6:46pm
He can make the operator << overload a member function - it just would not work well
at all as a member function.

This is why I suggested that he tried it both ways, then he could see the real limitations of having it as a member function for himself.
Last edited on Feb 27, 2012 at 7:01pm
Feb 27, 2012 at 10:44pm
guestgulkan. could you show how function operator << for streams can be a member of a class?
Feb 27, 2012 at 11:55pm
! was just trying to say - that at first you may be tempted to overload the << operator to output to a stream as part of a the class- but you will end up with something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using namespace std;



class MyClass
{

public:

    MyClass () :m_Val(99) {}

    MyClass& operator << ( ostream& os) //is this what the return type should be??
    {
        os << m_Val;
        return *this;
    }
private:
    int m_Val;

};


int main()
{

    MyClass mc;
    mc << cout; //weird
    return 0;

}


Which is most unusual and not the way everybody would expect it to be done by convention
//============================================================
//============================================================
But if the class was the sort of class that could be used as a source and/or sink
of object _ like a link list, then you could overload the << and >> operators as class members to retrieve or insert objects in the list.
Example:

1
2
3
4
MyLinkList  myList;
Node  nodeA, nodeB, nodeC;
/*... setup nodes */
myList << nodeA << nodeB << nodeC;








Topic archived. No new replies allowed.