Operator Overloading Notes
Operator Overloading Notes
Operator Overloading Notes
Operator Overloading
C++ allows you to redefine the meanings of operators, such as +, -, and =, for your classes.
Many object-oriented languages do not provide this capability, so you might be tempted to
disregard its usefulness in C++. However, it can be beneficial for making your classes
behave similarly to built-in types such as ints and doubles. It is even possible to write
classes that look like arrays, functions, or pointers!
The reasons vary for the different operators, but the general guiding principle is to make your
classes behave like built-in types. The closer your classes are to built-in types, the easier
they will be for clients to use. For example, if you want to write a class to represent fractions,
it's quite helpful to have the ability to define what +, -, *, and / mean when applied to objects
of that class.
We might require a function to manipulate objects of two distinct classes. Friend function
enables us to create a function as a friend of a class. This function can access the private
and protected members of the class. Both global functions and member functions of other
classes can be made a friend of the class.
Operator overloading is used to make user-defined data types closer to basic data types so
that user-defined data types can be part of a mathematical expression. For example, you
can use the addition (+) operator to add two integers: float or double values. The plus
operator can be overloaded to add two objects, as shown below:
myclass obj1, obj2, obj3;
obj3 = obj1 + obj2;
Operator overloading is used to increase the functionality of the existing operators of C++ so
that they are applied to user-defined data types rather than just being limited to basic data
types.
Some of the operators already mean two different things. For example, the – operator can
be used as a binary operator, as in x = y - z or as a unary operator, as in x = -y;. The *
operator can be used for multiplication or for dereferencing a pointer. The << operator is the
insertion operator or the left-shift operator, depending on context. You can overload both
meanings of operators with dual meanings.
Unary operators are operators that take one operand. They are classified as simple prefix
operators, increment and decrement operators, and type cast operators.
A simple prefix operator such as negation(!) and negative(-) operator may be defined by
a member function that takes no parameters, as shown below:
#include<iostream.h>
class INTEGER
{
private:
int x;
public:
INTEGER(int p=0) //Constructor
{
x=p;
}
//other functions
INTEGER operator -() //Overloaded the negative sign operator
{
INTEGER obj;
obj.x = -x;
return obj;
}
void display()
{
cout<<"x="<<x<<endl;
}
};//end of INTEGER class
void main()
{
INTEGER k=40; //Object of INTEGER class and 40 is passed as
//parameter
k.display ();
INTEGER m=-k; //Object of INTEGER class and -k is passed as parameter
m.display ();
}
The compiler distinguishes the prefix and postfix increment and decrement operators. When
you use the prefix and postfix operators for incrementing an object the syntax is as follows:
++<object_name>; //Using prefix increment operator
<object_name>++; //Using postfix increment operator
In the above syntax, both the statements are translated by the compiler using:
<object_name> operator ++();
The compiler distinguishes the prefix and postfix operators by the use of a dummy integer to
all postfix unary operators as shown below:
<object_name>++; /*Resolved by compiler as <object_name>.operator ++(0)*/
To overload the prefix and postfix increment operators you need to define the member
operator functions such as:
To overload the prefix and postfix decrement operators you need to define the member
operator functions such as:
<class_name> operator --() //Overloading prefix decrement operator
{
//function body
return <class_name_object>
}
<class_name> operator --(int) //Overloading postfix decrement operator
{
//Function body
return <class_name_object>
}
Example:
#include<iostream.h>
class INTEGER
{
private:
int x;
public:
INTEGER(int p=0) //Constructor
{
x=p;
}
void display()
{
cout<<"x="<<x<<endl;
}
void main()
{
INTEGER k=40;
k.display ();
++k;
k.display ();
INTEGER k1= k++;
k1.display ();
k.display ();
}
The following table lists all of the operators that you can overload, specifies whether they
should be methods of the class or global friend functions, summarizes when you should (or
should not) overload them, and provides sample prototypes, showing the proper return
values.
In this table, T is the name of the class for which the overloaded operator is written, and E is
a different type (not the name of the class).
Operator Name or Method or When to Sample Prototype
Category Global Overload
Friend
Function
operator+ Binary Global friend Whenever friend const T
operator- arithmetic function you want to operator+(const T&,
recommende provide const T&);
operator* d these
operator/ operations
for your
operator% class
operator- Unary Method Whenever const T operator-()
operator+ arithmetic and recommende you want to const;
bitwise d provide
operator~ operators these
operations
for your
class
operator++ Increment and Method Whenever T& operator++();
operator-- decrement recommende you
d overload
binary + const T operator++(int);
and -
operator= Assignment Method Whenever T& operator=(const T&);
operator required you have
dynamically
allocated
memory in
the object
or want to
prevent
assignment
, as
described
in Chapter
9
operator+= Shorthand Method Whenever T& operator+=(const
operator-= arithmetic recommende you T&);
operator d overload
operator*/ assignments the binary
operator/= arithmetic
operators
operator%
=
operator<< Binary bitwise Global friend Whenever friend const T
operator>> operators function you want to operator<<(const T&,
recommende provide const T&);
operator& d these
operator| operations
operator^
operator<< Shorthand Method Whenever T& operator<<= (const
= bitwise recommende you T&);
operator>> operator d overload
= assignments the binary
bitwise
operator&= operators
operator|=
operator^=
operator< Binary Global friend Whenever friend bool
operator> comparison function you want to operator<(const T&,
operators recommende provide const T&);
operator<= d these
operator>= operations
operator==
operator<< I/O stream Global friend Whenever friend ostream
operator>> operators function you want to &operator<< (ostream&,
(insertion and recommende provide const T&);
extraction) d these
operations
friend istream
&operator>> (istream&,
T&);
operator! Boolean Member Rarely; use bool operator!() const;
negation function bool or
operator recommende void*
d conversion
instead
operator&& Binary Global friend Rarely friend bool
operator|| Boolean function operator&&(const T&
operators recommende lhs, const T& rhs);
d
friend bool
operator||(const T& lhs,
const T& rhs);
operator[] Subscripting Method When you E& operator[](int);
(array index) required want to
operator support
subscriptin const E& operator[](int)
g: in array- const;
like classes
operator() Function call Method When you Return type and
operator required want arguments can vary; see
objects to examples in this chapter
behave like
function
pointers
operator Memory Method When you void* operator
new allocation recommende want to new(size_t size)
operator routines d control throw(bad_alloc);
new[] memory
allocation
for your void* operator
classes new[](size_t size)
(rarely) throw(bad_alloc);
operator Memory Method Whenever void operator
delete deallocation recommende you delete(void* ptr) throw();
operator routines d overload
delete[] the
memory void operator
allocation delete[](void* ptr)
routines throw();
operator* Dereferencing Method Useful for E& operator*() const; E*
operator-> operators required for smart operator->() const;
operator-> pointers
Method
recommende
d for
operator*
operator& Address-of N/A Never N/A
operator
operator->* Dereference N/A Never N/A
pointer-to-
member
operator, Comma N/A Never N/A
operator
operator Conversion, or Method When you operator type() const;
type() cast, operators required want to
(separate provide
operator for conversion
each type) s from your
class to
other types
Binary operators are operators that work on two operands, such as:
Arithmetic operators: +, -, *, %, and /
Arithmetic assignment operators: +=, -=, *=, /=, and %=
Comparison operators: >, <, <=, >=, ==, and !=
Overloading a binary operator is similar to overloading a unary operator except that the
binary operator requires an additional parameter, as shown:
//Program overloads the +, -, <, and == operators
#include<iostream>
using namespace std;
class INTEGER
{
private:
int x;
public:
INTEGER(int p=0)
{
x=p;
}
INTEGER operator +(INTEGER &k) //Overloading + operator
{
INTEGER obj;
obj.x = x + k.x;
return obj;
}
int main()
{
INTEGER i=50, j=90;
INTEGER k=i+j;
cout<<"Value in k after addition->";
k.display();
INTEGER m=j-i;
cout<<"Value in m after subtraction->";
m.display();
if (i<j)
cout<<" i is less than j"<<endl;
if (j==90)
cout<<" j is equal to 90"<<endl;
INTEGER g = -m;
g.display ();
return 0;
}
#include<iostream.h>
class INTEGER
{
//Declaring friend functions
private:
int x;
public:
friend INTEGER operator +(int v,INTEGER o);
INTEGER(int p=0)
{
x=p;
}
};
o.x = t + obj.x;
return o;
int main()
{
INTEGER i=50, j=90;
INTEGER k=i+j;
cout<<"Value in k after addition->";
k.display();
INTEGER m=j-i;
cout<<"Value in m after subtraction->";
m.display();
if (i<j)
cout<<" i is less than j"<<endl;
if (j==90)
cout<<" j is equal to 90"<<endl;
INTEGER a=20;
INTEGER d = 20 + a;
d.display ();
return 0;
}
Overloading the Function Call Operator
When you overload the ( ) function call operator, you are not, per se, creating a new way to
call a function. Rather, you are creating an operator function that can be passed an arbitrary
number of parameters. Let's begin with an example. Given the overloaded operator function
declaration
double operator()(int a, float f, char *s);
In general, when you overload the ( ) operator, you define the parameters that you want to
pass to that function. When you use the ( ) operator in your program, the arguments you
specify are copied to those parameters. As always, the object that generates the call (O in
this example) is pointed to by the this pointer
The class member access operator represented by the -> symbol, is a unary operator. The
syntax is as follows:
object->element;
The operator->() function returns a pointer to an object of the class that the operator->()
operates upon. The element must be a member that is accessible within the object. You can
create an equivalence between object var1 and object->var1 by overloading the class member
access operator that returns the this pointer
You can overload C++'s comma operator. The comma is a binary operator, and like all
overloaded operators, you can make an overloaded comma perform any operation you want.
However, if you want the overloaded comma to perform in a fashion similar to its normal
operation, then your version must discard the values of all operands except the rightmost.
The rightmost value becomes the result of the comma operation. This is the way the comma
works by default in C++.
Here is a program that illustrates the effect of overloading the comma operator.
#include <iostream>
using namespace std;
class loc {
int longitude, latitude;
public:
loc() {}
loc(int lg, int lt) {
longitude = lg;
latitude = lt;
}
void show() {
cout << longitude << " ";
cout << latitude << "\n";
}
temp.longitude = op2.longitude;
temp.latitude = op2.latitude;
cout << op2.longitude << " " << op2.latitude << "\n";
return temp;
}
return temp;
}
int main()
{
loc ob1(10, 20), ob2( 5, 30), ob3(1, 1);
ob1.show();
ob2.show();
ob3.show();
cout << "\n";
ob1 = (ob1, ob2+ob2, ob3);
return 0;
}
10 60
11
11
Notice that although the values of the left-hand operands are discarded, each expression is
still evaluated by the compiler so that any desired side effects will be performed.
Remember, the left-hand operand is passed via this, and its value is discarded by the
operator,( ) function. The value of the right-hand operation is returned by the function. This
causes the overloaded comma to behave similarly to its default operation. If you want the
overloaded comma to do something else, you will have to change these two features.
Assignments
2. Write a program for accessing class's public data member using object(not using pointer)
of the class and -> operator.
3. Overload the Subscript Operator []
4. Overload the function () Operator