This chapter begins by explaining that we could simplify the use of the clockType class from chapter 12 by extending the definitions of standard C++ operators. It would be convenient, for instance to be able to use the incrementation operator, the comparison operator, and the insertion operator on this class instead of using the functions that chapter 12 had you write to increment, compare, and output data from this class.
We could not use the standard operators because the only operators chapter 12 taught us to use (the only ones that would work on a class) were the assignment and member selection operators. This chapter explains how to write additional definitions for these operators. Doing so is called overloading the operators. Note: we are not redefining what the operators do. We are adding new abilities to those operators.
When we overload an operator, we are teaching it to do something new. The text explains that the division operator (/) is already overloaded, because it can do two kinds of division: integer division and floating-point division. We learned in the last chapter that the incrementation operator is overloaded, because it produces one kind of result if its operand is an integer, and another kind of result if its operand is a pointer.
It follows, then, that to overload an operator, we must
teach it to do something different when it has different
kinds of operands. To do this we write a function whose name
will be the word operator, immediately followed by the
operator we are overloading. Example:
The text explains that you must follow several rules (restrictions) when overloading an operator:
A question may need to be answered: why do we need to overload an operator? We need to do so if we want to use that operator with a class or a struct that we create.
The text briefly discusses this. Every object of any class has a hidden pointer to itself. That pointer is called this. For the purposes of this class, be aware that every object of every class has such a pointer, and it points to the object itself.
The text returns to the concept of friends by discussing
functions. This is a little odd. (Right. As though the other
concepts in the second half of the book aren't.) We declare a
friend function in a class, as though it was a member
of the class. The text states, however, that a friend function is not
a member of that class. Example:
We use the keyword friend in the prototype for the friend function to accomplish two things: the friend is granted access to all members of the class, and it is tagged as not being a member of the class itself.
So, why does this chapter care about friends? It is important because it relates to overloading operators. We have to write a function to overload an operator (teach it what to do with a new data type). If we are overloading an operator for a class, the function that we write can be a member of the class, or it can be a friend of that class. Making it a friend gives us the option of making it more modular and reusable for other classes.
There are more restrictions on friend vs. member:
More concise information on overloading can be found at C++ FAQ Lite.
A good discussion of templates can also be found at C++ FAQ Lite.