Section 3 - Operator Overloading

5A.3.1 Defining Operator Functions

Let's start with a definition of an operator function to be one whose name is

operatorX( ... )

where X is any valid C++ operator.

We will refine this definition, but as it stands, we can start forming examples. The plus sign, +, is a C++ operator, so that means we can define a function whose name is operator+. Next, we restrict the number of parameters to be either one or two -- one, if the original C++ operator is unary (^, !, ... ) and two, if it is binary (+, / *, ...).

Finally, we stipulate that at least one of the parameters be an object or object reference of some user-defined class.

So, our operator+() function could be defined as:

Dog operator+(Dog dog1, Dog dog2)
{
  Dog tempDog;

  tempDog.weight = (dog1.weight + dog2.weight) / 2; // avg weight
  tempDog.name = dog1.name + " " + dog2.name;   // concat names
  // or whatever else makes sense ...

  return tempDog;
}

where Dog is assumed to be a class. This means we have a new function that takes two Dogs, returns a Dog , and whose name is operator+().  I don't care what the function does right now.   I place a couple of random lines in the definition just to show you we could have it do anything.

To call it we could (but never would) use an ordinary function call:

Dog fido, watson, lucy;

fido = operator+(watson, lucy);

This is perfectly legal and in keeping with the modest definition of an operator function. Problem is, who needs a function with such a weird name.

The punch line is: You could call the above function using the more intuitive

fido = watson + lucy;

That is, the C++ compiler figures out the + between watson and lucy is neither numeric addition nor string concatenation, but a call to our function operator+(), and it knows to pass watson and lucy as arguments to the function.

Suddenly, we can make operators do different things than C++ would have them do. The main catch is that at least one of the two operands be a programmer-defined object.

Defining an operator function is called operator overloading because we have an overloaded meaning to the ordinary C++ operators.

The above example showed the hypothetical definition of a non-member operator function because it was not meant to be defined inside any class. Sometimes such an operator function has to be declared to be a friend of the class, particularly if it needed to access any private data of the class, as is often the case. However, we can also make an operator function a member, and if we do so, it would take one fewer parameters (omit the first parameter). What happens to the first parameter? Guess.

If you guessed that the first parameter does not have to be passed because the operator function uses the this object that called the function as its first parameter, you were correct. In the case above, if the + operator were a member operator, it would look something like this:

Dog Dog::operator+(Dog dog2)
{
  //...
}

5A.3.2  Remarks About Operators

Here are some important facts about operator overloading:

This last item is important and something that you should, at your level of expertise now, be able to really digest, understand and experiment with.  Go back to the lesson on copy constructors and deep copies and reread it, replacing the original idea of initializing an object without a copy constructor with the idea of assigning an object without an assignment operator.  You should be able to see the exact parallels and understand that the insides of the assignment operator overload should do, essentially, what the copy constructor did.  This, however, is only critical if you have deep data in your object.  If there is only shallow data, then neither a copy constructor nor an assignment operator overload is needed.