Operator Overloading
Operator Overloading
6.1 Introduction
In the previous unit you have studied the constructors, their different types
and their use in C++. You have also studied the destructors and the
namespaces in C++. In this unit you study the concept of operator
overloading. You will also learn how to overload different operators in C++.
You will also know the method of performing type conversions in C++.
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. Operator overloading, less commonly known as operator ad-hoc
polymorphism, is a specific case of polymorphism, where different operators
have different implementations depending on their arguments. Operator
overloading is generally defined by the language, the programmer, or both.
Operator overloading is claimed to be useful because it allows the
developer to program using notation "closer to the target domain” and
allows user-defined types a similar level of syntactic support as types built
into the language. In this unit we are going to discuss unary and binary
operator overloading with examples.
Objectives:
After studying this unit, you should be able to:
explain operator overloading
describe unary operator overloading
describe binary operator overloading
discuss type conversion
Manipal University Jaipur B2114 Page No.: 132
Object Oriented Programming – C++ Unit 6
sizeof operator
preprocessor symbol (#)
A special function called and operator function is used to overload an
operator. It defines the operations that the overloaded operator will perform
on the objects of the class for which it is redefined. An operator function is
defined either as a public function or as a friend function. You must follow
the following steps to overload an operator:
Create the class for which an operator is to be overloaded.
Declare the function either as a public function or a friend function.
Define the operator either inside the class definition (member function)
or outside the class (friend function).
The syntax to define the member operator function inside the class is
return_type operator op (parameter list)
{
//function body
}
Example: int operator + (int a, int b)
If you are defining member function outside the class you have to
declare it first inside the class. The following is the syntax to declare the
member function inside the class:
return_type operator op (parameter list);
The following is the syntax to define member operator function outside
the class:
return_type class_name:: operator op (parameter_list)
{
//function body
}
Example: int test :: operator + ( int a, int b)
Where return_type(int) = data type of the value returned by the function
operator is C++ keyword
c1++;
++c1;
cout<<c1.getcount();
}
c2=++c1;
cout<<c1.getcount()<<endl;
cout<<c2.getcount();
}
In the example shown above you can see that a counter variable is returned
without creating a variable. In the above implementation, we are returning
the counter variable without creating a variable. It is done by using a
constructor having one argument. When the statement return counter(c) is
executed, the value of the argument c of the invoking object is passed to the
constructor and a nameless object is created which is initialized to the value
stored in the count and returned to the calling program. One argument
constructor is used in this case. We are using one argument constructor in
this case.
The limitation of unary operator overloading is that the increment and
decrement operators cannot be totally duplicated. The reason is that the
C++ compiler is not able to differentiate between pre and post increment/
decrement operators.
Self Assessment Questions
4. Unary operators are implemented with _____ arguments.
5. Unary operators should have return value as ________.
6. Unary operators overloaded for the class can differentiate between
post and pre operators. (True/False)
{
float x; //real part
float y; //imaginary part
public:
complex(){ } //constructor1
complex( float real, float imag) //constructor2
{
x=real;
y=imag;
}
complex operator+(complex c);
void display(void);
};
complex complex:: operator+(complex c)
{
complex temp; //temporary
temp.x = x + c.x;
temp.y = y + c.y;
return(temp);
}
void complex :: display(void)
{
cout << x << “+ j” << y << “\n”;
}
int main()
{
complex c1, c2, c3; //invokes constructor1
c1= complex(2.5, 3.5); //invokes cosntructor2
c2=complex(1.6, 2.7);
c3=c1+c2;
cout<< “c1 = ” ;
Manipal University Jaipur B2114 Page No.: 139
Object Oriented Programming – C++ Unit 6
c1.display();
cout<<”c2 = ”;
c2.display();
cout<<”c3 = ”;
c3.display();
return 0;
}
Here is the output of the above program:
c1= 2.5 + j3.5
c2 = 1.6 + j2.7
c3 = 4.1 + j6.2
Let us look at the following function:
complex complex :: operator+(complex c)
{
complex temp; //temporary
temp.x = x + c.x;
temp.y = y + c.y;
return(temp);
}
{feet=0; inches=0;}
distance(int f)
{feet=f; inches=0;}
distance(int f, int i)
{feet=f;inches=i;}
void display()
{cout<<feet <<" "<<inches<<endl;}
friend distance operator + (distance, distance);
};
distance operator + (distance d1, distance d2)
{ int f = d1.feet+d2.feet;
int i = d1.inches+d2.inches;
return distance(f,i);}
void main()
{
distance d1(2,5), d2;
d2=10+d1;
d2.display();
}
Let us now study how the relational operators can be overloaded. In this
situation also there can be either one argument or two argument
overloading (using friend function). But the return value should be integer (0
or 1) which indicates true or false.
The following program implements the program for relational operator
overloading (<) for the distance class.
# include<iostream.h>
class distance
{ private:
int feet, inches;
public:
distance()
{feet=0; inches=0;}
distance(int f)
{feet=f; inches=0;}
distance(int f, int i)
{feet=f;inches=i;}
void display();
void getdata();
int operator < (distance d1)
{ if (feet<d1.feet)
return 1;
else if (feet==d1.feet) && (inches<d1.inches)
return 1;
else
return 0;
}
};
void distance :: display()
{cout<<feet <<" "<<inches<<endl;}
void distance :: getdata()
{ cout<<”Enter distance in feet and inches”;
cin>>feet >>inches;}
void main()
{
distance d1,d2;
d1.getdata();
d2.getdata();
if (d1<d2)
cout<<d1.display() << “is smaller”;
else
cout<<d2.display()<< “ is smaller”;
}
Manipal University Jaipur B2114 Page No.: 144
Object Oriented Programming – C++ Unit 6
As you can see in the above program the object d1 is responsible for
invoking the operator < whereas object d2 is passed as an argument. The
value returned by the overloaded operator function is either 1 or 0 which
indicates true or false respectively. Certain compilers support boolean
datatype which can be alternatively used instead of integer. The display and
getdata member functions are implemented in a different way in the above
program. You can observe that the member functions are declared inside
the class but defined outside the class. The class name with the function
name separated by scope resolution operator (::) is used to specify that the
member function belongs to the distance class.
Self Assessment Questions
7. Member functions of a class can be defined outside the class using
________ operator along with the class name.
8. In most of the cases same result is generated either by using member
function or by using friend function. (True/False).
9. Overloaded relational binary operators should return _________.
10. Left operand calls the operator in case of binary operator overloading.
(True/False).
6.6 Summary
Operator overloading allows defining new meaning for normal C++
operators and specifies how it can be used with the user defined classes.
Overloading should be used only to imply default meanings to avoid
confusion in its usage.
Not all operators can be overloaded. C++ enables the programmer to
overload most operators to be sensitive to the context in which they are
used.
The compiler generates the appropriate code based on the operator's
use. Operator overloading contributes to C++'s extensibility.
Operator overloading provides the same concise expressions for user-
defined types that C++ provides with its rich collection of operators that
work on built-in types.
The precedence and associativity of an operator cannot be changed by
overloading.
6.8 Answers
Self Assessment Questions
1. True
2. True
3. operator
4. No
5. Same as class datatype
6. False
7. scope resolution operator
8. True
9. Integer or Boolean values
10. True
11. Type Conversion
12. Castings
Terminal Questions
1. //string.cpp
# include<iostream.h>
# include<ctype.h>
# include<string.h>
# include<conio.h>
class string
{ char str[25];
public:
string()
{ strcpy(str, "");}
string(char ch[])
{ strcpy(str, ch);}
void display()
{ cout<<str;}
string operator ++()
{string temp;
int i;
for(i=0;str[i]!='\0';i++)
temp.str[i]=toupper(str[i]);s
temp.str[i]='\0';
return temp;
}
};
void main()
{ clrscr();
string s1="hello", s2;
s2=s1++;
s2.display();
getch();
}
2. //stringar.cpp
# include<iostream.h>
# include<ctype.h>
# include<string.h>
# include<conio.h>
class string
{ char str[25];
public:
string()
{ strcpy(str, "");}
string(char ch[])
{ strcpy(str, ch);}
void display()
{ cout<<str;}
void operator +=(string s2)
{int i,l,j;
l=strlen(str);
for(i=l,j=0; s2.str[j]!='\0'; i++,j++)
str[i]=s2.str[j];
str[i]='\0';
}
};
void main()
{ clrscr();
string s1="hello", s2="world";
s1+=s2;
s1.display();
getch();
}
3. In case of overloading of unary operators, the calling operand can be
either left or right of the operator as in case of increment and decrement
operators. While defining the operator functionality for the class, the
keyword operator is used. Refer section 6.3 for more details.
Manipal University Jaipur B2114 Page No.: 152
Object Oriented Programming – C++ Unit 6
References:
Object Oriented Programming with C++ - Sixth Edition, by
E Balagurusamy. Tata McGraw-Hill Education.
Object-Oriented Programming using C++, by Satchidananda Dehuri,
Alok Kumar Jagadev, Amiya Kumar Rath. PHI Learning Pvt. Ltd.