Friend Functions
5.2. Friend Functions#
Operator overloading can be implemented using member functions, for example, the +
operator when the left operand is an object of the class. However, when the left operand is not an object of the class, we cannot use member functions to overload the operator.
For example, consider the following code that overloads the <<
operator to print out Complex
objects:
Complex z(3, 4);
cout << z; // calls what function?
Cannot have operator<<
as member of ostream
: In the expression cout << z
, the left operand is an object of the ostream
class. We cannot interpret this expression as cout.operator<<(z)
because we cannot change the ostream
class to have a member function that takes a Complex
object as an argument. This is because ostream
is part of the C++ standard library, and we cannot modify it.
Cannot have operator<<
as a member of Complex
: Since the left-hand side is not Complex
object, we cannot use a member function of the Complex
class to overload the <<
operator.
Solution: Have operator<<
as a non-member function that takes an ostream
object and a Complex
object as parameters. This way, we can overload the <<
operator to work with ostream
and Complex
objects.
Another problem! Private members of Complex
need to be accessed: operator<<
needs to access the private members of the Complex
class to print out the real and imaginary parts. How can we allow a non-member function to access the private members of a class?
The final solution is to define operator<<
as a friend function of the Complex
class. A friend function is a non-member function that (i) has access to the private members of the class in which it is declared as a friend. Also, (ii) it allows the left operand to be of a different type.
For example, we can declare operator<<
as a friend function of the Complex
class using the friend
keyword before the function prototype as follows:
class Complex {
// ...
friend <<return type>> operator<<(<<parameter list>>);
};
Step 1: Understand the function prototype
Input parameter list. The function operator<<
should receive cout
and z
from cout << z
as parameters. The left-hand side cout
is an object of the ostream
class and is received as the first parameter. Then, the right-hand side z
is an object of the Complex
class and is received as the second parameter.
All streams are passed by reference to avoid making a copy of the stream object. It gives a compile error if we pass the stream by value. Hence, the parameter list should be ostream& os, const Complex& rhs
. Here, z
is passed as a const
reference because we do not want to modify the Complex
object when printing it.
So far, we have the following function prototype:
friend <<return type>> operator<<(ostream& os, const Complex& rhs);
Return type. In C++, we can chain multiple <<
operators together, for example:
cout << "z is " << z << endl;
A friend function is not a member of the class, so it is defined outside the class.