0

I've pored over information regarding friend functions and their use. They're able to access encapsulated data within a class while not breaking one of the golden rules of OOP. In purveying various source code for overloading the I/O operators (A basic operation, one of the first taught in learning C++) every one defines the operator as a friend as implements it outside of the class. My question is: does this need to be done? Why not just declare the function as a public member of the class and insert/display data from the class while keeping everything encapsulated? It seems no different than overloading other operators, yet it is a supposedly traditional approach to overloading the I/O operators.

Thanks for your time.

Taylor Bishop
  • 479
  • 2
  • 5
  • 18
  • possible duplicate of [Overload operators as member function or non-member (friend) function?](http://stackoverflow.com/questions/1905439/overload-operators-as-member-function-or-non-member-friend-function) – Ben Voigt Apr 29 '13 at 00:29

2 Answers2

2

Let's say you want to overload operator<< for your class X, so you can use it like this:

X x;
std::cout << x;

Notice that std::cout is the first operand of the operator. To implement this as a member function, it would have to be a member of std::basic_ostream, which is the type of std::cout. You can't add members to an already defined class. That's why we declare it as a free function instead.

If you overloaded operator<< as a member of X, it would be taking an X object as its first operand, so you would use it like this:

X x;
x << something;

This is obviously not what you want when dealing with I/O.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
0

If you have an overloaded operator like: a @ b implemented as a member function, that call is translated to a.operator@(b);. That means the function must be a member of the class that's the type of the left operand. In the case of iostreams, that would be all the operators needed to be members of the iostream itself.

While iostreams do provide some insertion/extraction operators as members, you normally want to be able to add more without modifying the iostream class itself1. To do that, you pretty much need to implement the operator as a free function instead of a member function. Since you normally still want it to have access to the private parts of whatever type you're planning to read/write (insert/extract, if you prefer) it typically has to be a friend of that class.


  1. This is an example of the so-called open/closed principle: the class should be open to extension, but closed to modification. In other words, you want to extend it without modifying it.
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111