Operator overloading is the ability to tell the compiler how to perform a certain operation when its corresponding operator is used on one or more variables. For example, the compiler acts differently with regards to the subtraction operator “-“ depending on how the operator is being used. When it is placed on the left of a numeric value such as -48, the compiler considers the number a negative value. When used between two integral values, such as 80-712, the compiler applies the subtraction operation. When used between an integer and a double-precision number, such as 558-9.27, the compiler subtracts the left number from the right number; the operation produces a double-precision number. When the - symbol is doubled and placed on one side of a variable, such as --Variable or Variable--, the value of the variable needs to be decremented; in other words, the value 1 shall be subtracted from it. All of these operations work because the subtraction operator “-” has been reconfigured in various classes to act appropriately.

If you write an expression such as SriLanka + BanglaDesh and want to display the result, the compiler would need to know what you are trying to achieve. Do you want to add the names of the countries and create a new string name? Do you want to get the result of their combined populations, or the total or their areas? Operator overloading allows you to help the compiler perform this type of operation when it is applied on your
object(s).

Defaults Methods: A Review

When studying constructors, we learned that, whenever you create an object, the compiler automatically creates some of its necessary methods. For example, you can create a TSquare class as follows:

To allow making copies of objects, the compiler also creates an appropriate constructor for you if you do not define one for your object. This is called the copy constructor. You can still explicitly create one as follows:

In reality, there are four default functions that the compiler creates for you if you do not define them yourself. Besides the default constructor, the copy constructor, and the destructor, the compiler also create an overloaded assignment operator function for you. This can be easily seen on the code completion if you have not yet created this function for an object:

So far, we have been able to assign a variable declared from a class to another variable of the same type. Here is an example:

This assignment operation is possible because the compiler is configured to take care of it, using its own default created overloaded assignment operator function.

Overloading an Operator

The C++ language recognizes 45 operators of various types. The most usual and the most regular operator is the output extraction operator << used to display anything in C++. The input >> operator is used to retrieve data input. Arithmetic operators are used to perform numeric operations. The unary operators are used to control the sign or behavior of a variable. There are many other binary and C++ specific operators. When customized, the arithmetic and any other operators can be applied to varying circumstances.

When overloaded, the operators are implemented as functions using the operator keyword. For example, the syntax of overloading the addition operator “+” would be operator+().

Overloading the Operators

The Assignment Operator

The assignment operator works by giving the value of one variable to another variable of the same type or closely similar. Suppose you declare two integer variables as follows:

This time, once a variable has been initialized, it holds the appropriate value. Notice that the B variable that has not been initialized is still holding garbage. If you want to give the value of one variable to another variable, you can use the = operator between them as follows:

The = sign implements the assignment operation. It works on two variables, one on each side of the symbol. After it has operated, the value that the right variable holds is given to the left variable. An example of executing the above program would be:

Notice that although the A variable had been initialized previously, by assigning it to another variable, its value changes. On its second call, the A variable has lost its previous variable and hods whatever value the B variable was given.

The first time the variables are called, the initialized A variable displays a recognizable value while B is still holding garbage. After B has been initialized, on the second call, both variables hold the same value:

To use the assignment operator on your own object, you should (or must) let the compiler know how to handle the assignment operator on a variable declared from such an object. To do this, create your own implementation of the assignment operator.

The assignment operator is defined using the operator keyword followed by the = symbol and the traditional parentheses of every function. As a function, the operator must be declared in the body of the class, along with the other method members. In order for this function to be accessible outside of the class, it should be listed in the public section. Like any member method, the function should have a return value, at least void. Therefore it could be created as follows:

We saw earlier that, to perform an assignment, one variable is given the value of another, similar, variable, as in Var1 = Var2. The variable on the right is given the value of the variable on the left. For this operation, we must have a source variable (right) whose value we want to assign to the other variable (left). We must make sure that this source variable is the same type as the value we are trying to get; otherwise, the compiler would not be able to perform the operation. Therefore, the source variable will be provided as argument to the function; and this argument must be the same as the class on which the operation is applied. For this reason, the function operator can be created as:

void operator=(TRectangle Rect);

To assign one variable to another, there must be a correspondence between a member of the source variable and a member of the target or left variable. Therefore, the function operator can be implemented as follows:

The assignment operator is simply used to assign the value of a source variable to another variable. During this operation, the value of the source variable is not modified. Therefore, the argument should be passed as a constant. This changes the function to:

void operator=(const TRectangle Rect);

To speed up the retrieval of the value of the argument, you can let the compiler access the value of the argument directly to its address. This is done by passing the argument as reference. Since the argument is (also) passed as a constant, there is no modification of the value of the argument. The function can be declared as:

void operator=(const TRectangle& Rect);

We saw earlier that when one variable is assigned to another, as in B = A, the value of the source variable A is given to the target or left variable B. This means that, after the operation, the function should return a non-void variable. Since the new value of the variable must be the same as the source variable, the function should return a variable of the same class. The operator function would become:

TRectangle operator=(const TRectangle& Rect);

When a variable is assigned a value, its own value must change, regardless of the value it was holding; we saw this earlier when we called the A variable after it had been assigned the value of B. Therefore, the operation should return a reference to the type of object. This changes the decclaration of the function to:

TRectangle& operator=(const TRectangle& Rect);

From this, the function must return a value, since it is not defined with void anymore. The assignment operation is performed from one object to another object of the same kind. This means the function must return the same variable that called it. Therefore, the function must return the this pointer. Here is the correct implementation of the function:

In C++, the addition operation is applied with the + symbol. Depending on the circumstance, it can be considered a unary or a binary operator. It is used as a unary operator when applied to one variable.

The addition binary operator is used on two variables to add their values. Suppose you have two variables A and B. To add their values, you would type A + B. You can display such a value on the console as follows:

As you can see, the binary addition operator is performed on two variables. To apply it on a class, you must create a function operator that takes two arguments. Since the values of the arguments will not be modified, you should pass them as constant references. The function can be declared as follows:

To implement the function, you would add the values of the arguments. When performing this operation, there must be a correspondence between a variable of one argument and the equivalent variable of the other argument. Therefore, you would implement the function as follows:

If you execute the program with the function declared in the public section, you would get an error because C++ does not allow a binary operator to be overloaded (with two or more arguments) in a class. The solution is to declare the function outside of the class. The problem is that, to perform this binary operation, you will need access to the private or protected members of the class. Therefore, the operator function must be declared as a friend of the class:

Since the operator+() function is declared as void, which means it does not return any value, it does not provide a value that can be displayed on the console. For example the following does not make sense:

Refering to the former program that added A and B, instead of displaying the result of A + B on the console, you might want to store it in another variable. To do that, you would perform the addition and then assign the result to another variable. The assignment would appear as follows:

This demonstrates that the binary addition applied on two variables in fact provides a third result; and this result is a variable of the same type. In other words, after performing the addition, the operator+() function must return a variable of the same type. The function should return TRectangle and can be declared as follows:

This time, the function must return a variable of the same type. During its implementation, you can declare a new variable of the same type, assign each of its variables to the equivalent added variable of the arguments, and then return that variable. Here is an example:

By overloading the addition operator, you can apply this operation to a variable declared from a class. To add a constant to the variable, you must create a version of the operator+() function that would take a constant and add it to the desired variable. After the operation is performed, the function must return a new variable that holds the new value (if the function does not return a value, the operation would be useless; you cannot display it on the console and you cannot assign the result to another variable). Therefore, the function would be declared as follows:

The implementation of the function depends on what you are trying to achieve. For example, you can decide to add the constant value to only one member variable of the class. After performing the operation, the function must return the same variable on which it was applied, which is represented with the this pointer:

The expression A += 350.44 is equivalent to A = A + 350.44. In other words, the constant value 350.44 is added to the variable A and renders the same variable A without the need of another variable. Besides adding a constant number to itself, a variable can also add the value of another variable of the same type to itself and thus modify the value it is holding. This is illustrated in the following:

The += operation allows a variable to add a constant value to itself and change its (own) value after the operation. By default, this operation cannot be performed on a class. As we saw with adding a constant to a variable declared from a class, we can create our own version of the += operator to help the compiler figure out what to do when this operator is applied on our object.

The addition assignment operator “+=” works by assigning a value to a variable and hold a new value. The compiler will need to know what value is being added to the variable. Therefore, you must provide an argument that specifies this value. If this value is a variable of the same type that is being worked on, you must provide it by changing the function as:

void operator+=(TRectangle Rect);

The value of such an argument will not be modified in the function; it will only serve as the source of the value that is being added. For this reason, it should be passed as a constant. As long as it is not being modified, to speed up code execution, you should pass it as reference. The function would then change to:

The implementation of this function simply consists, once more, of deciding what to add and what to leave out. For our example, we will add a member variable of the TRectangle variable that is making the call to the corresponding member variable of the argument:

You can implement the function by deciding what member function would be modified. For this example, we will add the constant argument to each member variable of the class variable that is making the call:

When the += operatotor is called by a variable, the value of the variable is modified. Because the += is a binary operator, it is forcefully applied on two value. After its execution, it results in a new value that can be assigned to another variable. Since a value is returned, it is safer to return a non-void value. The return value should be the same as the variable that made the call. This would change the function as follows:

Now, the compiler expects the function to return a value. Since the variable that makes the call is also the same that is returned, the function should return the object that called it. This is done by returning the this pointer:

Boolean operators are used to compare the values held by two variables of a program. For example, the >= binary operator is used to find out whether one value is greater than another, as illustrated in the following main() function:

To perform this operation, the compiler examines the value of each variable. If the left variable has a value greater than that of the right variable, the comparison returns true; otherwise, the comparison returns false. This means a comparison opration is in fact a function that applies to two variables. Because the C++ compiler does not allow an overloaded operator to take two arguments, the function must be declared outside of the class. Since the function needs to have access to the private (or protected) members of the variables, it should be declared as a friend of the function. The data type common to Boolean operations and functions is bool and will be used to return the result of comparison functions:

Once again, the implementation of this function depends on the class or the intended result. For example, if the class is a square or any regular polygon, because its sides are equal, you can perform the comparison on the length of the sides:

If the program consists of a restaurant menu, you can perform the comparison on the number of items ordered. If the classes are bank accounts, you can compare the balance on each account. In reality, every overloaded operator depends on your intentions and can be applied on one or more member variables and you can decide what validates the truthfulness of the comparison. For a geometric figure like the rectangle, we will compare the area of each rectangle. When the area of the left rectangle is greater than the area of the right rectangle, we will decide that the left rectangle if greater than the right rectangle:

As it does with regular variables, the compiler can be configured appropriately when the output operator is applied to a variable declared from a class. This makes it possible to write a statement such as:

TCountry Pais;
cout << Pais;

To appropriately display a variable on the console, you must overloaded the output << operator and tell the compiler how to behave when this operator is used on the variable. The function used to perform this operation is structured as operator<<(). Like any of the operators we have used so far, the compiler needs to know what variable is being worked on. Therefore, you must at least pass this variable as argument. When the output operator is executed, the intention is only to display the value(s) of the variable without modification. For this reason, the argument should be passed as a constant reference:

Any data display on the screen is managed by a class called ostream. This class communicates to the << operator how data must be displayed. Therefore, if you want to control how the compiler would display data, you must pass this class to your operator. Because the variable will be modified, in order to keep the modification performed on the variable, you should pass it as reference. This changes the function to:

Since the ostream is an external class, make sure you include its header file, which is iostream.h. Now that the overloaded operator function is using two variables, it cannot be part of the class: you must declare it outside of the class. In order for the function to access private (and/or protected) member variables of the class, you should make it a friend of the class. The function becomes:

To implement this function, once again, tell the compiler what to do with it. You can access some members or each member variable of the class whose values you want to display and define how their values must be displayed. For this exercise, we will list the dimensions of the rectangle the way the corrdinates or a Cartesian point are displayed:

In practical terms, the output operator “<<” is a binary operator: it operates on two values. Consequently, it provides a result in the form of a third value. This means the operator<<() function should return a value. Because it is applied on the ostream class which allows it to tell the ostream class how to display data on the right side of the operator, the ostream argument is the one that gets modified and that is being worked on. The second argument, in this case the TRectangle is simply the source of data that will be displayed. Therefore, the function should return an instance of the ostream class. This means the function should be declared as follows:

In the same way, you can write an overloaded version of the input operator. Its syntax would be: operator>>(). The class used to request values from the console is istream. To apply this operator, you should pass both an istream object and an instane of the class whose variables you want to request. Following the same logic applied to the output operator, the function would be declared as follows:

Now the cin >> operator can use an instance of your class the same way it would request the value of a regular variable. The cout and cin as defined can be called from any function. Here is an example: