0% found this document useful (0 votes)
49 views27 pages

Week 10

The document discusses operator overloading in C++. It explains that operators can be overloaded to work with user-defined data types by defining operator functions. Operator functions can be member functions or global functions. The document provides examples of overloading unary operators like ++, binary operators like +, and stream operators << and >>. It also discusses how to perform conversions between basic data types and user-defined classes using constructors and conversion functions.

Uploaded by

Vijay Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views27 pages

Week 10

The document discusses operator overloading in C++. It explains that operators can be overloaded to work with user-defined data types by defining operator functions. Operator functions can be member functions or global functions. The document provides examples of overloading unary operators like ++, binary operators like +, and stream operators << and >>. It also discusses how to perform conversions between basic data types and user-defined classes using constructors and conversion functions.

Uploaded by

Vijay Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 27

Operator Overloading

To obtain the services from objects, we usually send the


messages (in the form of function call) to the objects.
This function call notation is cumbersome for certain
kind of classes, such as mathematical classes.
In such situations, operator notation is more convenient.
In C++, we can make existing operators work with user
defined data types by overloading the operators, so that
when they are used with objects, they have meaning
appropriate to those objects.
The term operator overloading refers to giving C++
operators, such as +, *, <= etc. additional meaning when
they are applied to user defined data types such as
classes.

An operator is overloaded by writing a non-static member


function definition or a global function definition with the
function name operator followed by the symbol for the
operator:
returnType operator symbol(parameters)

For example:
void operator + ()

Operator function can be a member function or a global


function.

When operator function is implemented as a member


function, the leftmost (or only) operand must be an object
(or reference to an object) of the operators class.

If the left operand of an overloaded operator must be an


object of a different class or a fundamental type, this
operator function must be implemented as a global
function.
A global operator can be made a friend of a class if that
function must access private or protected data members
of that class.
One reason to choose a global function to overload an
operator is to enable the operator to be commutative.

Overloading Unary Operators:


A unary operator for a class can be overloaded as a nonstatic member function without arguments or a global
function with one argument that must be an object (or a
reference to an object) of the class.
returnType operator symbol()
//member function
returnType operator symbol(argument)
//global function

class Counter
// overloading unary ++ operator
{ private:
// (prefix ++) class member function
unsigned int count;
public:
Counter(): count(0)
{
}
unsigned int get_count()
{return count; }
void operator ++ ()
{++count;}
};
int main()
{Counter c1, c2;
cout << c1 = << c1.get_count();
cout << \nc2 = << c2.get_count();
++c1; ++c2; ++c2;
Output:
cout << \nc1 = << c1.get_count();
c1 = 0
cout << \nc2 = << c2.get_count();
c2 = 0
}
c1 = 1
c2 = 2

class Counter
// overloading unary ++ operator
{ private:
// (prefix ++) global function
unsigned int count;
public:
Counter(): count(0)
{
}
unsigned int get_count()
{return count; }
friend void operator ++ (Counter &);
};

void operator ++ (Counter & c)


{++c.count;}
int main()
{Counter c1, c2;
cout << c1 = << c1.get_count();
cout << \nc2 = << c2.get_count();
++c1; ++c2; ++c2;
cout << \nc1 = << c1.get_count();
cout << \nc2 = << c2.get_count();
}

Output:
c1 = 0
c2 = 0
c1 = 1
c2 = 2

The overloaded increment operator defined in above


programs will not work in an assignment operation. The
following code will complain an error:
Counter c1, c2;
c2 = ++c1;

// error

To make the overloaded operator ++ work in an


assignment operation, the operator function should return
a Counter type.

This is illustrated in the following program.

class Counter
// overloading unary ++ operator
{ private:
// (an object of the class is returned)
unsigned int count;
public:
Counter(): count(0)
{
}
Counter(int c): count(c)
{
}
unsigned int get_count()
{return count; }
Counter operator ++ ()
{++count;
return Counter (count);
// a nameless object of
}
// Counter is returned
};
int main()
{Counter c1, c2;
cout << c1 =
cout << \nc2 =
++c1;
c2 = ++c1;
cout << \nc1 =
cout << \nc2 =
}

<< c1.get_count();
<< c2.get_count();

<< c1.get_count();
<< c2.get_count();

Output:
c1 = 0
c2 = 0
c1 = 2
c2 = 2

The above program can be simplified by using the this


operator as follows:
class Counter
{ private:
unsigned int count;
public:
Counter(): count(0)
{
}
unsigned int get_count()
{return count; }
Counter & operator ++ ()
{++count;
return *this;
}
};

The overloaded unary ++ operator described in above


programs works as a prefix increment operator.
It will not work if we try to use it as a postfix operator.
The overloaded postfix increment operator has the
syntax
returnType operator symbol(int)
//member function
returnType operator symbol(argument, int)
//global function

The int is not really an argument, it is used only to


distinguish between the prefix and postfix notation.

Overloading Binary Operators:

A binary operator can be overloaded as a non-static


member function with one parameter or as a global
function with two parameters, one of those parameters
must be a class object or a reference to a class object.
returnType operator symbol(argument)
//member function
returnType operator symbol(argument1,
argument2)
//global function

class Distance
// overloaded function +
{ private:
int feet; float inches;
public:
Distance(): feet(0), inches(0.0)
{ }
Distance(int ft, float in): feet(ft), inches(in)
{ }
void getdist()
{cout << "Enter feet " ; cin >> feet;
cout << "Enter inches "; cin >> inches; }
void showdist()
{cout << feet <<"\' - " << inches << '\"' << endl;}
Distance operator + (Distance) const;
};
Distance Distance::operator + (Distance dist2)const
{ int f = feet + dist2.feet;
float i = inches + dist2.inches;
if(i >= 12.0) {i -= 12.0; f++; }
return Distance(f, i); // returns a nameless object
}

int main()
{ Distance d1(10, 5.5);
Distance d2(8, 9.7);
Distance d3 = d1 + d2;
Distance d4 = d1 + d2 + d3;
cout << "d1 = " ; d1.showdist();
cout << "d2 = " ; d2.showdist();
cout << "d3 = " ; d3.showdist();
cout << "d4 = " ; d4.showdist();
}
Output:
d1 = 10' - 5.5"
d2 = 8' - 9.7"
d3 = 19' - 3.2"
d4 = 38' - 6.4

Overloading arithmetic assignment operator:


The use of overloaded arithmetic assignment operator is
illustrated by the following example, which uses
overloaded operator += .
void Distance::operator += (Distance d2)const
{ int f += feet + d2.feet;
float i += inches + d2.inches;
if(i >= 12.0)
{i -= 12.0;
feet++; }
}
int main()
{ Distance d1;
d1.getdist();
Distance d2(5, 6.5);
Distance d1 += d2;
cout << "d1 = " ; d1.showdist();
cout << "d2 = " ; d2.showdist();}

Overloading Stream Insertion and Stream Extraction


Operators:
C++ allows to overload stream extraction operator <<
and stream insertion operator >> for customizing input
and output.
The following program illustrates the use of overloaded
operators << and >>.

class PhoneNumber
// overloaded operators << and >>
{friend ostream & operator <<(ostream &, const PhoneNumber &);
friend istream & operator >>(istream &, PhoneNumber &);
private:
string areaCode, exchange, line;
};
ostream & operator <<(ostream & output, const PhoneNumber
&number)
{output << ( << number.areaCode << ) << number.exchange <<
- << number.line;
return output; }
ostream & operator >>(istream &input, PhoneNumber &number)
{input.ignore;
// skip (
input >> setw(3) >> number.areaCode;
input.ignore(2)
// skip ) and space
input >> setw(3) >> number.exchange;
input.ignore()
// skip (-)
input >> setw(4) >> number.line;
return input; }

int main()
{PhpneNumber phone;
cout << Enter phone number in the form (123) 456-7890: <<
endl;
cout << The phone number entered was:
cout << phone << endl;
}

Run:
Enter phone number in the form (123) 456-7890:
(800) 555-1212
Enter phone number entered was:
(800) 555-1212

Data Conversion:
It is common to represent data in different forms. It involves
the conversion of data from one form to another; for
example, conversion from radians to degrees, etc.

The assignment between basic types or user defined data


types of same types is done automatically by the compiler.
To convert between user defined types, such as classes, and
basic types we need to write these routines ourselves.
To convert data from a basic type to a user defined type, the
conversion function should be defined in the objects class in
the form of a constructor.
constructor(basicType)
{ // steps for conversion
}

class Meter
{private: float length;
Meter() length(0.0)
{
}
Meter(float initlength)
{ length = initlength/100;
};

In case of conversion from a user defined type to a basic type,


the conversion function should be defined in objects class in
the form of an operator function.
The operator function is defined as an overloaded basic data
type which takes no arguments.
It converts the data members of an object to basic data types
and returns a basic data-item.
operator basicType()
{ // steps for conversion
}

class Meter
// conversion from basic-type to objects
{private: float length;
// and vice-versa
public:
Meter() length(0.0)
{
}
Meter(float initlength)
// basic-type to object
{length = initlength/100;}
operator float()
// object to basic-type
{ float lengthcms;
lengthcms = length*100.0;
return lenghtcms;}
void getLength()
{cout << Enter length in meters << endl;
cin >> length;}
void showLength()
{cout << Length in meters = << length << endl;}
};

int main()
{Meter meter1, meter2;
float length1, length2;
cout << Enter length in cms << endl;
cin >> length1;
meter1 = length1;
//basic type to object
meter1.showLength();
meter2.getLength();
length2 = meter2;
//object to basic type
cout << Length in cms = << length2 << endl;
}
Run
Enter length in cms
220
Length in meters = 2.2
Enter length in meters
1.30
Length in cms = 130

class String
// conversion between C-type string
{private: char str[50];
// and string objects
public:
String()
{str[0] = \0; }
String(char s[])
// C-string to string
{ strcpy(str, s); }
void display()
{cout << str << endl;}
operator char*()
{ return str;}
};

// String to C-string

int main()
{String s1; char str1[] = Raj Kumar;
s1 = str1;
s1.display();
String s2 = Ravi S.;
char *str2;
str2 = s2;
cout << s2 << endl;
}

Conversion between objects of different classes:


C++ compiler does not support the conversion between
objects of different classes.
Data conversion in such situations is achieved by using a
conversion function.
In an assignment statement such as
objecta = objectb;

objectb is the source object and objecta is the

destination object.
The conversion function may be defined in the source
objects class as an operator function or as a one-argument
constructor in the destination objects class.

const float PI = 3.1415; //conversion b/w radians and degrees


class Radian
{private: float rad;
public:
Radian(): rad(0.0)
{}
Radian(float initrad)
{ rad = initrad;}
float getradian()
{return rad;}
void input()
{cout << "Enter radian: "; cin >> rad;}
void display()
{cout << "Radian = " << getradian() << endl;}
};
class Degree
{private: float degree;
public:
Degree(): degree(0.0)
{}

Degree(Radian radian)
//conversion at destination object
{degree = radian.getradian()*180/PI;}
float getdegree()
{return degree;}
operator Radian()
//conversion at source object
{ return (Radian(degree*PI/180.0));}
void input() {cout << "Enter degree: "; cin >> degree;}
void display() {cout << "Degree = " << degree << endl;}
};
int main()
{Degree deg1, deg2; Radian rad1, rad2;
deg1.input();
rad1 = deg1;
// uses operator Radian()
rad1.display();
rad2.input();
deg2 = rad2;
// uses Degree(Radian rad)
deg2.display();}
Run
Enter degree: 120
Radian = 2.09433
Enter radian: 1.20
Degree = 68.757

Overloading the subscript operator [ ]:


In an array a, the element a[i] simply represents *(a+i)
because a is the address of the base element of the array
and so (a+i) is the address of the ith element of a.
The symbol [] denotes the subscript operator. Therefore
the expression a[i] is equivalent to operator [](a, i).
Like other operators, we can overload [].
The following program overloads [] so that an array a[]
can check its bounds, that is, it can check that the index
numbers used to access a[] are not out of bounds.

class Safearray
// overloading []
{private: int a[50];
public:
int & operator[](int n)
{if(n < 0 || n >= 50)
cout <<Index out of bounds; exit(1);}
return a[n];}
};
int main()
{Safearray sa;
for(int i=0; i<50; i++)
sa[i] = i*10;
for(int j=0; j<50; j++)
{int temp = sa[j];
cout << Element << j << is << temp << endl;
}
}

You might also like