# Lesson 31

### Lecture Overview

The topic of this lecture is Operator Overloading. In previous lectures, we discussed
about it a bit while discussing about references. So we will see in detail what is operator
restrictions on it.

Operator overloading is to allow the same operator to be bound to more than one
implementation, depending on the types of the operands.
Page 390
As you know that there are standard arithmetic operators in C/C++ for addition ( + ),
subtraction ( - ), multiplication ( * ) and division ( / ). We should only use these operators
for their specific purposes. If we want to add two ints, say i and j, the addition will take
place in the following manner i.e. i + j. To add two double numbers, we use the same
operator and write d1 + d2. We may add two floats with the help of the same operator as

### Where is it Relevant to Apply?

Firstly, the operator overloading gets relevant whenever there is the application of the
mathematical functions of addition, subtraction, multiplication and division. Complex
number is one example of it. As discussed earlier, in case of Date class, the operators can
be effectively used to get the future or past dates.
Secondly, the operators are also used sometimes in case of non-mathematical
manipulation. The example of String class to manipulate strings help us understand it in
a better way. The operator + can be used to concatenate two strings. Previously, we used

### strcat() function declared inside string.h header file to concatenate two strings. As compared to strcat(), the use of + to concatenate two strings is definitely easier and more readable. But there is a little bit cost associated with this process of operators overloading. The cost is involved whenever we overload an operator. We have to write a function and make use of the operator semantics correctly while implementing the function. This means that the function written to overload + operator should do addition or concatenation of strings in case of String objects. Page 391

There are two types of operators to overload:
1. Unary
2. Binary
Unary operators are the ones that require only one operator to work. Unary operators are
applied to the left of the operand. For example, ^, &, ~ and !.
Binary operators require two operands on both sides of the operator. +, -, *, /, %, =, <
and > are examples of binary operators.
The complete list of C++ operators that can be overloaded is as follows:
+ - * / % ^ &
| ~ ! = < > +=
-= *= /= %= ^= &= |=
<< >> >>= <<= == != <=
>= && | | ++ - - -> * ,
[ ] ( ) new new[ ] delete delete[ ]
The following operators can’t be overloaded.
. : :: .* ? sizeof
class. The data member day can be accessed as follows:

### operator is the keyword here. An example of this will be as follows: Complex operator + (Complex & ); Page 392 We sometimes write only operator to refer to the operator function in our discussion.

Operators must be declared as class members.
- The arity (number of operands) cannot be changed. If you are overloading an operator
that requires two operands e.g. *. It cannot be used as a unary operator that requires
one operand.
- No new operators can be created. Like in Fortran language, we have ** as ‘raise to
the power (exponent) operator’ but this operator does not exist in C++. Therefore, it
can’t be overloaded. Hence, only existing operators of C++ are used.
- Overloading can’t be performed for the built-in (sometimes called primitive or native)
data types. For example, we cannot change how two ints are added. That means that
operators are overloaded to use with defined data types like classes.
- Precedence of an operator cannot be changed. For example, the * has higher
precedence than +. This precedence cannot be changed.
- Associativity of an operator cannot be changed. If some operator is right associative,
it cannot be changed to be left associative.

Let’s take the complex number’s class Complex and define a + operator function.
We know that when we write the following line:
x = y + z ;

### y and z operands are take part in the addition operation but there is no change in them due to this operation. This is the + operator’s functionality. The resultant is being assigned to the variable x. This is assignment operator’s functionality. Now we will discuss a little bit about the assignment operator as well. Let’s say we write the following statement for two complex numbers c1 and c2. c1 = c2 ; Here c2 is being assigned to c1. Will this assignment work when we have not written any assignment operator function for complex number? Apparently, it looks that the statement will produce a compilation error (as there is assignment operator defined by us) but this is not true. Whenever, we write our own class and compile it, the compiler automatically generates a default assignment operator. The default assignment operator makes a member to member assignment. This works fine unless there is a pointer data member inside our class and that pointer is pointing to some data inside memory. For that case (when there is a pointer data member) we have to write our own assignment operator Page 393 otherwise the default assignment operator works fine for us. That will be discussed in the subsequent lectures. By definition of addition of complex numbers, we know that whenever two complex numbers are added, the real part of one number is added into the real part of other number. Similarly, the imaginary part of one number is added to the imaginary part of the other number. We also know that when a complex number is added to another complex number, the resultant is also a complex number consisting of real and imaginary parts. This addition of real, imaginary parts and return of resultant complex number is the functionality of the + operator function we are going to write. Another thing to decide for this + operator is whether this operator will be a member operator or a friend operator. Normally, operators are member operators but there are situations when they cannot be member operators. In case of member operator, following is the syntax of its prototype: Complex operator + (parameter-list); For member operator, the object on the left side of the + operator is driving this +

operation. Therefore, the driving object on the left is available by this pointer to +
operator function. But the object on the right is passed explicitly to the + operator as an
argument.
We can define a member operator as under:
1. Complex Complex :: operator + (Complex c)
2. {
3. Complex temp ;
4. temp.real = real + c.real ;
5. temp.imag = imag + c.imag ;
6. return temp ;
7. }
Let’s see this code line by line.
Line 1 indicates that the return type is Complex, it is an operator + function and it is
accepting a Complex object by value as an argument.
In line 3, a local Complex object is declared, called temp.
In line 4, real part of the calling object (that is the one, driving) on the left of the +
operator is being added to the real part of the object c, where c is passed as an argument.
In line 5, imag part of the calling object (that is the one, driving) on the left of the +
operator is being added to the imag part of the object c, where c is passed as an argument.
In line 6, the Complex object temp containing the resultant of + operation is being
returned by value.
In our code, we can write something as:
Complex c1, c2, c3 ;
. . .
. . .
c3 = c1 + c2 ;
Page 394
In the above statement ( c3 = c1 + c2; ), c1 is the object that is calling or driving the

### Non-member Operator Functions

Now we are much clear that when an operator function is implemented as a member
function, the leftmost operator must be a class object or reference to a class object of the
operator’s class.
When an operator function is implemented as a non-member function, the left-most
operand may be an object of the operator’s class, an object of a different class, or a builtin
type. Now we discuss it in a detailed manner.
We can always write our operators as non-member functions. As a non-member
functions, the binary operators like + gets both the operands as arguments. One thing to
take care of while writing non-member functions that they cannot access the private
Page 396
members of classes. Actually, this is just to this reason that we make those non-member
functions as friends to the classes whose private data members are required to be
accessed. But the question arises, can we write a non-member operator function without
making it a friend of a class. The answer to this question is yes; If there are public
member functions to access the private data members of the class then they serve the
purpose. In this case of Complex class, let’s say we have two public member functions:
double real( );
double imaginary( );
to access the private data members real and imag respectively. Then we can write nonmember

### operator + function as: Complex operator + (Complex& c1, Complex& c2) { Complex temp; temp.real ( c1.real() + c2.real() ); temp.imaginary ( c1.imaginary() + c2.imaginary() ); return temp; } But this non-member operation functions without declaring a friend of the class is definitely slower than the member function or a friend one. The reason for this is obvious from the code that it is making three additional function calls of real() and imaginary()

for each private data member. Also it is not easy to write as compared to member
functions. Therefore, it is recommended to write the member functions for operators
Let’s take an example where the operators are performing a non-arithmetical operation.
We are writing a class String for strings manipulation as:
class String
{
private :
char string [ 30 ] ;
public :
String ( )
{
strcpy ( string , "" ) ;
}
void getString ( )
{
cout << "Enter the String : " ;
cin >> string ;
Page 397
}
void displayString ( )
{
cout << "The String Is : " << string << endl ;
}
// Declaration (prototype) of overloaded sum operator
String operator + ( String & s ) ;
};
We want to write + operator to concatenate two strings. Firstly, we will see the operator’s
behavior in ordinary context (behavior with primitive variables for example) and try to
implement the same behavior for this class. We want to concatenate two strings (two

### Example Program 1

Rudimentary implementation of a class named Complex class to cater complex numbers.
A + operator function has been implemented to add two complex numbers.
/* This program implements the basic class for complex numbers and demonstrates +
operator function */
#include <iostream.h>
class Complex
Page 398
{
private :
double real ; // Real Part
double imag ; // Imaginary Part
public :
/* Parameterless Constructor */
Complex ( )
{
cout << "\n Parameterless Constructor called ..." ;
}
/* Parameterized Constructor */
Complex ( double r, double i )
{
cout << "\n Parameterized Constructor called ...";
real = r ;
imag = i ;
}
/* Setter of real data member */
void real ( double r)
{
real = r ;
}
/* Getter of the real data member */
double real ( )
{
return real ;
}
/* Setter of the imag data member */
void imaginary ( double i )
{
imag = i ;
}
/* Getter of the imag data member */
double imaginary ( )
{
return imag ;
}
Page 399
/* A Function to display parts of a Complex object */
void display ( )
{
cout << "\n\n Displaying parts of complex number ...";
cout << "\n Real Part : " << real << endl ;
cout << " Imaginary Part : " << imag << endl ;
}
/* Declaration (prototype) of overloaded sum operator */
Complex operator + ( Complex & c2 ) ;
};
Complex Complex :: operator + ( Complex & c1 )
{
cout << "\n Operator + called ...";
Complex temp ;
temp.real = real + c1.real ;
temp.imag = imag + c1.imag ;
return temp ;
}
void main ( )
{
Complex c1 ( 1 , 2 ) ; // Consturct an object using the parameterized constructor
Complex c2 ( 2 , 3 ) ; // Consturct another object using the parameterized
// constructor
Complex result ; // Construct an object using a parameterless constructor
result = c1 + c2 ; // Call the Operator + to add two complex numbers (c1 & c2)
// and then assign the result to 'result' object
result.display ( ) ; // Display the result object contents
}
The output of the program is as follows:
Parameterized Constructor called ...
Parameterized Constructor called ...
Parameterless Constructor called ...
Operator + called ...
Parameterless Constructor called ...
Displaying parts of complex number ...
Real Part : 3
Page 400
Imaginary Part : 5
The + operator function can be enhanced to return reference of Complex object. We can
also implement += operator. += operator and the enhanced operator + are implemented
as:
Complex & Complex :: operator + ( Complex & c1 )
{
real = real + c1.real ;
imag = imag + c1.imag ;
return *this;
}
// Declaration (prototype) of overloaded sum assignment operator definition
Complex & Complex :: operator += ( Complex & c2 )
{
real += c2.real ;
imag += c2.imag ;
return *this;
}

### Example Program 2

Rudimentary Implementation of String class to manipulate strings. It uses + operator to
concatenate strings.
/* This program implements the basic class for strings and demonstrates + operator
function to concatenate two strings*/
#include <iostream.h>
#include <string.h>
class String
{
private :
char string [ 30 ] ; // Array to store string
public :
/* Parameterless Constructor */
String ( )
{
strcpy ( string , "" ) ;
Page 401
}
/* Getter function of string */
void getString ( )
{
cout << "Enter the String: " ;
cin >> string ;
}
/* Function to display string */
void displayString ( )
{
cout << "The String is : " << string << endl ;
}
// Declaration (prototype) of overloaded sum operator
String operator + ( String & s ) ;
};
String String :: operator + ( String &s )
{
String temp ;
strcpy ( temp.string , "" ) ;
strcat ( temp.string , string );
strcat ( temp.string , s.string );
return temp;
}
void main ( )
{
String string1 , string2 ; // Declared two String objects
string1.getString ( ) ; // Get string for string1 object
string2.getString ( ) ; // Get string for string2 object
String hold = string1 + string2 ; // Concatenate string1 and string2 and store the
// result in hold object
hold.displayString ( ) ; // Display the string
}
The output of the above program is as follows:
Enter the String: Operator
Page 402

### Tips

- There are two types of operators to overload: unary and binary.
- C++ built-in operators work for built-in (primitve) types but for user defined data
types, user has to write his/her own operators.
only existing C++ operators are overloaded without creating a new one in the
language. Also, it should not impact the type, semantics (behavior), arity (number of
operands required), precedence and associativity of the operator.
- For binary member operators, operands on the left drives (calls) the operation.
- Operator functions written as non-members but friends of the class, get both the
operands as their arguments.
- Operators can be written as non-members and even without making them friends. But
this is tedious and less efficient way, therefore, it is not recommended.