You are on page 1of 43

Operator Overloading

Operator Overloading Fundamentals


◈ C++ allows the use of certain operators in some other
meaning apart from its usual meaning
◈ Operator overloading provides a flexible option for the
creation of new definitions for most of the C++ operators
◈ For eg, the operator ‘+’ can be overloaded to add two
complex numbers
◈ However, when an operator is overloaded, its original
meaning is not lost

Prepared by Sherin Joshi


Operator Overloading Fundamentals
◈ If the ‘+’ operator is overloaded, it can still be used to add
two integers
◈ Although semantics of an operator can be extended, we
cannot change its syntax (number of operands, precedence
and associativity)

Prepared by Sherin Joshi


Restrictions of Operator Overloading
◈ There are certain restrictions and limitations to be kept in
mind while overloading operators:
Only existing operators can be overloaded. New operators
cannot be created.
The overloaded operator must have at least one operand
that is of user-defined type.
We cannot change the basic meaning of an operator. That
is to say, we cannot redefine the plus(+) operator to
subtract one value from the other.

Prepared by Sherin Joshi


Restrictions of Operator Overloading
Overloaded operators follow the syntax rules of the
original operators. They cannot be overridden.
There are some operators that cannot be overloaded:
sizeof [Size of operator]
. [Membership operator]
.* [Pointer-to-member operator]
:: [Scope resolution operator]
?: [Conditional operator]

Prepared by Sherin Joshi


Restrictions of Operator Overloading
We cannot use friend functions to overload certain
operators. However, member functions can be used to
overload them:
= [Assignment operator]
() [Function call operator]
[] [Subscripting operator]
-> [Class member access operator]

Prepared by Sherin Joshi


Restrictions of Operator Overloading
Unary operators, overloaded by means of a member
function, take no explicit arguments and return no explicit
values, but, those overloaded by means of a friend
function, take one reference argument (the object of the
relevant class).
Binary operators overloaded through a member function
take one explicit argument and those which are overloaded
through a friend function take two explicit arguments.

Prepared by Sherin Joshi


Restrictions of Operator Overloading
When using binary operators overloaded through a
member function, the left hand side operand must be an
object of the relevant class.
Binary arithmetic operators such as +, -, *, and / must
explicitly return a value. They must not attempt to change
their own arguments.

Prepared by Sherin Joshi


General Syntax
◈ The general syntax for operator overloading is as follows:
return_type operator
operator_to_be_overloaded(parameters);

◈ Here, “operator” is a keyword


◈ Operator functions must be either non-static member
functions or friend functions

Prepared by Sherin Joshi


Binary Operator Overloading
//(1)Assignment operator overloading (using member function)
#include <iostream>
using namespace std;
class Sample {
private:
int x,y;
public:
Sample(int, int);
void operator =(Sample);
void display( );
}; Prepared by Sherin Joshi
Sample::Sample(int a,int b) {
x = a, y = b;
}
void Sample::operator =(Sample obj) {
x = obj.y;
y = obj.x;
}
void Sample::display( ) {
cout << endl << "x = " << x;
cout << endl << "y = " << y;
}

Prepared by Sherin Joshi


int main( )
{
Sample obj1(20,30), obj2(5,7);
obj1.display( );
obj2.display( );
obj2 = obj1; //overloaded definition called
obj1.display( );
obj2.display( );
return 0;
}

Prepared by Sherin Joshi


//(2)Comparison operator overloading
//Using member function
#include <iostream>
using namespace std;
class Sample {
private:
int x;
public:
void setvalue( ) {
cout << "Enter value : ";
cin >> x;
}
Prepared by Sherin Joshi
int operator < (Sample obj2)
{
if(x < obj2.x) {
return x;
}
else {
return obj2.x;
}
}
};

Prepared by Sherin Joshi


int main( )
{
Sample s1,s2;
s1.setvalue( );
s2.setvalue( );
int res;
res = s1 < s2; //overloaded definition called
//res = s1.operator <(s2);
cout << endl << "Smaller value = " << res;
return 0;
}

Prepared by Sherin Joshi


//(3)Arithmetic operator overloading
//Using friend function
#include <iostream>
using namespace std;
class Complex {
private:
int real, img;
public:
Complex( ) {
real = 0;
img = 0;
}
Prepared by Sherin Joshi
Complex(int real, int img)
{
this->real = real;
this->img = img;
}
friend Complex operator + (Complex, Complex);
void display( )
{
cout << real << " + " << img << "i";
}
};

Prepared by Sherin Joshi


Complex operator + (Complex obj1, Complex obj2)
{
/*Complex temp;
temp.real = obj1.real + obj2.real;
temp.img = obj1.img + obj2.img;
return temp;*/
//nameless temporary object
return Complex(obj1.real + obj2.real, obj1.img + obj2.img);
}

Prepared by Sherin Joshi


int main( )
{
Complex c1(2,3),c2(5,1),c3;
c3 = c1 + c2; //overloaded definition called
cout << "c1 = ";
c1.display( );
cout << endl << "c2 = ";
c2.display( );
cout << endl << "c3 = ";
c3.display( );
return 0;
}
Prepared by Sherin Joshi
Unary Operator Overloading
//(1)Postfix and Prefix operator overloading (using member function)
#include <iostream>
using namespace std;
class Counter {
private:
int count;
public:
Counter( ) {
count = 0;
}
Prepared by Sherin Joshi
Counter (int count) {
this->count = count;
}
int show( ) {
return count;
}
Counter operator ++ ( ) {
return Counter(++count); //nameless temporary object
}
Counter operator ++ (int) {
return Counter(count++); //nameless temporary object
} };
Prepared by Sherin Joshi
int main( ) {
Counter c1(5), c2;
cout << "c1 = " << c1.show( ) << endl;
cout << "c2 = " << c2.show( ) << endl;
++c1; //overloaded definition called
cout << "c1 = " << c1.show( ) << endl;
c2 = ++c1; //overloaded definition called
cout << "c2 = " << c2.show( ) << endl;
c2 = c1++; //overloaded definition called
cout << "c1 = " << c1.show( ) << endl;
cout << "c2 = " << c2.show( ) << endl;
return 0; }
Prepared by Sherin Joshi
//(2)Unary minus overloading
//Using friend function
#include <iostream>
using namespace std;
class Sample {
private:
int x,y,z;
public:
void getData(int a, int b, int c) {
x = a, y = b, z = c;
}

Prepared by Sherin Joshi


void showData( ) {
cout << "x = " << x << "\t\ty = " << y << "\t\tz = " << z << endl;
}
friend Sample operator - (Sample);
};
Sample operator - (Sample s) {
s.x = - s.x;
s.y = - s.y;
s.z = - s.z;
return s;
}

Prepared by Sherin Joshi


int main( )
{
Sample s1, s2;
s1.getData(-11, 22, -33);
s1.showData( );
s2 = -s1;
s2.showData( );
return 0;
}

Prepared by Sherin Joshi


Arrow Operator Overloading

#include <iostream>
using namespace std;
class Test {
public:
int num;
Test(int num)
{
this->num = num;
}

Prepared by Sherin Joshi


Test* operator ->( )
{
return this;
}
};

int main( )
{
Test obj(5);
cout << obj -> num;
return 0;
}
Prepared by Sherin Joshi
Overloading Stream Insertion and Stream
Extraction Operators
◈ ‘cout’ is an object of ‘ostream’ class and ‘cin’ in an object of
‘istream’ class
◈ As we know, if an operator is overloaded as member, then
it must contain an object of the class on the left hand side
of the operator
◈ The operators ‘<<’ and ‘>>’ are used as ‘cout<<a’ and
‘cin>>b’

Prepared by Sherin Joshi


Overloading Stream Insertion and Stream
Extraction Operators

◈ So, if we want to overload them using a member method,


then they must be made members of ‘ostream’ and ‘istream’
classes, which is not a good option
◈ Therefore, these operators are usually overloaded using a
friend function(which can also access private data
members) with two parameters or a global function

Prepared by Sherin Joshi


//A program to input and output a complex number using
//overloaded stream insertion and stream extraction operator
#include <iostream>
using namespace std;
class Complex
{
private:
int real, imag;
public:
friend istream & operator >> (istream &in, Complex &c);
friend ostream & operator << (ostream &out, Complex &c);
};
Prepared by Sherin Joshi
istream & operator >> (istream &in, Complex &c) {
cout << "Enter real part : ";
in >> c.real;
cout << endl << "Enter imaginary part : ";
in >> c.imag;
return in;
}

ostream & operator << (ostream &out, Complex &c) {


out << c.real;
out << " + " << c.imag << "i";
return out;
}
Prepared by Sherin Joshi
int main( )
{
Complex c1;
cin >> c1;
cout << endl << "Entered complex object : ";
cout << c1;
return 0;
}

Prepared by Sherin Joshi


Data Conversion
1. Conversion between basic types
2. Conversion from basic type to user-defined type
3. Conversion from user-defined type to basic type
4. Conversion between user-defined types of different
classes
i. Routine in source object
ii. Routine in destination object

Prepared by Sherin Joshi


Conversion between Basic Types
◈ Implicit: If we write a statement
intvar = floatvar;
the compiler will call a special routine to convert the floating
point value of ‘floatvar’ to an integer format so it can be
assigned to ‘intvar’
◈ Explicit: We can also force the compiler to convert one
type to another using cast operator
eg: intvar = static_cast<int>(floatvar);

Prepared by Sherin Joshi


Conversion from Basic Type to User-Defined
(Object) Type
//Conversion of meters(basic type) to Distance i.e. feets and inches
//(user-defined type)
#include <iostream>
using namespace std;
const float MTF = 3.280833; //meter to feet
class Distance {
private:
int feet;
float inch;
Prepared by Sherin Joshi
public:
Distance( ) {
feet = 0;
inch = 0.0;
}
Distance(float meter) //Conversion Constructor
{
float floatfeet = MTF * meter;
//feet = static_cast<int>(floatfeet);
feet = int(floatfeet);
inch = 12*(floatfeet - feet);
}
Prepared by Sherin Joshi
void displaydist( ) {
cout << "Converted Value is: " << feet << " FT " << inch << " IN";
} };
int main( ) {
float meters;
cout << "Enter value in meters: ";
cin >> meters;
Distance dist;
dist = meters; //Basic to User-defined
dist.displaydist( );
return 0;
}
Prepared by Sherin Joshi
Conversion from User-Defined (Object) Type to
Basic Type
//Conversion of user-defined type(Distance) to basic type(meters)
//Using overloaded casting operator (Conversion operator)
#include <iostream>
using namespace std;
const float MTF = 3.280833; //meter to feet
class Distance {
private:
int feet;
float inch;
Prepared by Sherin Joshi
public:
Distance( )
{
feet = 0;
inch = 0.0;
}
Distance(int ft, float in)
{
feet = ft;
inch = in;
}
Prepared by Sherin Joshi
operator float( ) //Overloaded casting operator / Conversion
{ //operator
float feetinfractions = inch/12;
feetinfractions += float(feet);
return (feetinfractions/MTF);
}
};
int main( )
{
int feet;
float inches;

Prepared by Sherin Joshi


cout << "Enter distance in Feet and Inches.";
cout << "\nFeet:";
cin >> feet;
cout << "Inches:";
cin >> inches;
Distance dist(feet, inches);
//User-defined to basic
float meters = dist; //Calls overloaded casting operator
//Alternatively: float meters = static_cast<float>(dist);
cout<<"Distance in Meters: "<< meters;
return 0;
}
Prepared by Sherin Joshi
Note
◈ There are 3 conditions that need to be satisfied for an
overloaded casting operator (conversion operator):
1. Overloaded casting operator doesn’t have any return
type.
2. It cannot take any parameters i.e. no argument can be
passed to an overloaded casting operator.
3. Finally, it has to be defined inside a class definition. The
class definition will be the user-defined data type that we
want to convert into a basic type whose casting operator
has been overloaded.
Prepared by Sherin Joshi
Conversion between User-Defined Types
of Different Classes
◈ Routine in source object
Refer to “times1.cpp”

◈ Routine in destination object


Refer to “times2.cpp”

Prepared by Sherin Joshi

You might also like