|
Introduction to operator Overloading
We already know that a function can be
overloaded (same function name having
multiple bodies). The concept of
overloading a function can be applied
to operators as well. This session
deals with overloading of operators to
make Abstract Data Types(ADTS) more
natural, and closer to fundamental
data types.
Need for Operator Overloading
Most fundamental data types have
pre-defined operators associated with
them. For example, the C++ data type
int, together with the operators +, -,
*, and /, provides an implementation
of the mathematical concepts of an
integer. To make a user-defined data
type as natural as a fundamental data
type, the user-defined data type must
be associated with the appropriate set
of operators.
Recall the fps_distance class, a
user-defined class, which implements
the British way of measuring distance.
The declaration of the class is given
below:
class fps_distance
{
private:
int iFeet;
float fInch;
public:
fps_distance(int iFt,float fIn)
{
iFeet = iFt;
fInch = fln;
}
void disp_dist(void)
{
cout<<Distance =<<iFeet<< <<fInch<<
<<endl;
}
};
If you want to add two distances
stored in two objects of the
fps_distance class, a function needs
to be invoked. For example,
object3.add_dist(object1, object2);
In this case, object1 is added to
object2 and the result is stored in
object3.
Similarly, to compare two distances,
the following function call can be
used:
object1.comp_dist(object2);
Here, the member function comp_dist of
object1 is invoked with object2 as a
parameter. This function compares the
data members of object1 with those of
object2 and returns the difference
between them.
Using operators you can add two
objects of the fps_distance class as
follows:
object3 = object1 + object2;
where object1, object2 and object3 are
all objects of the fps_distance class.
The above statement is clearer and
easier to comprehend then the function
call. Similarly, two objects of
fct_distance can be compared as
follows:
object1>object2
or
object1<object2;
or
object1==object2;
The user can understand the operator
notation more easily as compared to a
function call because it is closer to
the real-life implementation. Thus, by
associating a set of meaningful
operators, manipulation of an ADT can
be done in a conventional and simpler
form. Associating operators with an
ADT involves overloading them.
Recall the example discussed earlier
where we added two objects of the
fps_distance class and stored the
result in a third object using an
operator.
object3 = object1+object2;
Note that the same + operator that
is used to add integers behaves
differently when applied to the ADT
fps_distance.
Operator overloading refers to giving
additional meaning to the normal C++
operators when they are applied to
ADTs. Only the pre-defined set of C++
operators can be overloaded. An
operator can be overloaded by defining
a function for it. The function for
the operator is declared by using the
operator keyword.
|
+ |
- |
* |
/ |
% |
^ |
& |
| |
~ |
! |
|
= |
< |
> |
+= |
-= |
*= |
/= |
%= |
^= |
&= |
|
|= |
<< |
>> |
<<= |
>>= |
== |
!= |
<= |
>= |
&& |
|
|| |
++ |
-- |
, |
->* |
-> |
( ) |
[ ] |
new |
delete |
|
new[] |
delete[] |
|
|
|
|
|
|
|
|
|
| |
|
Table
22.1 List of Operators
that can be Overloaded |
|
Table 22.1 List of Operators that can
be overloaded
Unary operators are those which act on
a single operand. Example of unary
operators include the increment (++)
and decrement (--) operators. Program
22.1 overloads the ++ operators for
the fps_distance class to increment
the data member iFeet by 1.
Class fps_distance
{
..
void operator++(void)
{
iFeet++;
}
..
};
void main()
{
fps_distance Fps(10,10.2);
++Fps;
Fps.disp_dist(); //displays 11
}
In Program 22.1, an object of the
fps_distance class is created. The
data member iFeet of the FPS object is
incremented by using the overloaded ++
operator. Unary operators are those
which act on a single operand.
Examples of unary operators include
the increment(++) and decrement(--)
operators.
Prefix and Postfix
Note that in Program 22.1 ++
operator has been used as a prefix
operator. Le us now discuss this
aspect of operator overloading.
The prefix application of an operator
causes a variable to be incremented
first before it is used in an
expression while the postfix
application causes the value to be
incremented after the value is used in
an expression.
However, the ++ operator overloaded
in Program 22.1 cannot be used as a
postfix operator. An operator function
without any arguments is invoked by
the compiler for the prefix
application of the operator. The
compiler invokes the operator function
with an int argument for the postfix
application of the operator.
For example,
int operator ++(int);
The int argument here is a dummy
argument that is sued only to
distinguish between the prefix and the
postfix application. The expression:
++x;
translates to
x.operator++();
and the expression:
x++;
translates to
x.operator++(0);
The value zero is automatically sent
by the compiler.
Binary operators are operators that
work with two operands. Examples of
the binary operators include
arithmetic operators (+, -, *, /, %),
arithmetic assignment operators (+=,
-=, *=, /=) and comparision
operators(<.>,<= >=, ++, !=).
Overloading a binary operator is
similar to overloading a unary
operator except that a binary operator
requires an additional parameter.
Program 22.2 overloads the + binary
operator to add two objects of the
fps_distance class.
#include<iostream.h>
class fps_distanc
{
private:
int iFeet;
float fInch;
public:
fps_distance(int,float); //contructor
fps_distance();
fps_distance operator +(fps_distance&);
//to overload the + operator
void disp_distance(void); //display in
feet and inches
};
fps_distance :: fps_distance(int iFt,
float fln)
{
iFeet = iFt;
fInch=fln;
}
fps_distance :: fps_distance()
{
iFeet =0;
fInch=0.0;
}
/* The + operator needs two
operands, one passed as a parameter
and the other as the implicit object
*/
fps_distance fps_distance :: operator
+ (fps_distance &Fps2)
{
int iF = iFeet + Fps2.iFeet;
float fl = fInch + Fps2.fInch;
if (fl >= 12.0) //if the sum of inches
is more than or equal to 12,
//iFeet has to be incremented by one
{
fl-=12.0;
iF++;
}
return fps_distance(iF,fl);
}
//Function to display in feet and
inches
void fps_distance :: disp_distance()
{
cout<<Distance=<<iFeet<<,<<fInch<<,<<endl;
}
void main()
{
fps_distance Fps1(11,11.5);
fps_distance Fps2(10,10.7);
fps_distance Fps3;
Fps3 = Fps1 + Fps2;
Fps3.disp_distance();
}
In Program 22.2, the + operator is
overloaded to add two objects of the
fps_distance class. To add two
fps_distance class objects, the feet
and inches are added separately and a
nameless object is returned. The
operator function receives one object
as parameter. In the program, Fps1 is
the object of which the operator is a
function and Fps2 is the object passed
as parameter to the operator. Hence,
it needs only one argument. Whenever
an overloaded operator is invoked, the
object on the left side of the
operator is the object of which the
operator is a member, and the variable
or constant on the right side is the
parameter to the operator.
Similarly, comparison operator can
also be overloaded as follows:
..
int operator > (fps_distance &Fps2)
{
float fTemp1 = iFeet * 12 +fInch;
float fTemp2 = Fps2.iFeet * 12 +
Fps2.fInch;
return ((fTemp1 > fTemp2) ? 1 : 0);
}
..
The > overloaded operator compares
an objects of the fps_distance class
with iFeet.
|