C++: Friend Functions and Operator Overloading
Friend functions? What?!? C++ has friend functions. Seriously. It shouldn’t, but it does. There is only one reason, and it has to do with how C++ designed operator overloading.
Operators are all the built-in computations in a programming language, and are often represented by punctuation symbols; ‘+’ means numeric addition, ‘/’ means numeric division, ‘==’ means an equality test, ‘>’ means greater than, and so on. Some operators are a bit more complex – ‘[]’ is an array indexing operator that takes an array name on the left and the index value inside.
Most programming languages have built-in meanings for all of these operators, and C++ does too. But C++ allows you to extend these meanings! Most programming languages do not allow this. This is called operator overloading, since you add new meanings to the operators on top of their already built-in meanings.
You should almost NEVER use operator overloading on your own!!!
There are some libraries that require you to use it in order to take better advantage of their capability, but you should not just create your own use of operator overloading without very hard thinking about your design and why you want it. There is good reason that most programming languages do not have operator overloading: it messes with our brains too much!
Friend Functions
You should NEVER use friend functions on your own!!! (see discussion about operator overloading above).
Recall that C++ is designed as an extension of the C programming language—so a C++ program can contain plain functions that are not inside any class. Java, for example, does not allow this: in Java everything has to be in some class.
The designers of C++ decided that there are times when it is useful to allow a plain function to have access to the private members of an object. This is a bad idea and breaks encapsulation, but they did it anyway!
The mechanism behind it is the idea of a friend, which is a keyword in C++. Declaring something as a friend means that it has access to the private members it is friend to. C++ allows both classes and functions to be friends.
There is literally less than an 0.0001% chance you will have a good reason to use friends in any good OO design. So don’t. Except for the next section.
Operator Overloading
In C++, operator overloading is (almost) always done to define the meaning of an operator for a class, so that the objects of the class can be manipulated with the operator. For example, the ‘+’ operator is defined for the std::string class to mean string concatenation.
To define a new meaning of an operator means that you have to write code for it. Code is always inside a function/method. C++ operator code can be in a class method, but only in certain situations (e.g., the object must be on the left of a binary operator). Otherwise, the code must be in a plain function, not in a method. Since it is likely that the operator code will need access to private members of the object, the operator function must be declared as a friend.
Because the iostream package is centered around using the operators ‘«’ and ‘»’ for stream output and input, the most common operator to overload is one of these (typically ‘«'). In the class declaration (public section), the operator needs declared as (e.g., for class Customer):
friend std::ostream& operator<<(std::ostream& os, const Customer& customer);
Then in the implementation source, the operator function needs written, like:
std::ostream& operator<<(std::ostream& os, const Customer& customer)
{
os << "Customer: " << customer.name << " ";
if (customer.isLate) {
os << "is behind on payment";
} else {
os << "is up to date on payment";
}
return os;
}
Typically, you want to make the ‘«’ ostream operator “print the object” in a way that makes sense, so that anyone who uses it will get something sensible. Once you have this operator defined, then you can use an object directly in any output stream operation:
std::cout << customer << "\n";
Again, do NOT use operator overloading extensively, and be very careful!
Resources
None right now.