Friday 31 May 2013

Operator Overloading in C++


Introduction Operator Overloading
  • Operator overloading provides a flexible option for the creation of new definition for most of the C++ operators.
  • When an operator is overloaded its original meaning is not lost.

Consider the following example:
#include<iostream.h>
class complex
{
     private:
     int a,b;
     public:
     void getdata();
     void showdata();  
};
void complex:: getdata()
{
     cout<<”Enter two numbers”;
     cin>>a>>b;
}
void complex:: showdata()
{
     cout<<”a=”<<a<<”b=”<<b;
}
void main()
{
  complex c1,c2,c3;
  c1.getdata();
  c2.getdata();
  c3=c1+c2;  //Error
  c3.show();
}

l  Notice line c3=c1+c2;
l  This line generates compile time error.
l  Error occurs as operands to the operator ‘+’ are not of primitive type; rather they are of complex type. Every primitive data type is enriched with several operators. Defining working of operators is responsibility of programmer who defines data type. Hence, we have to define behavior of operator ‘+’ for complex.
l  Defining new meaning of ‘+’ does not make any loss to previous meaning of operator ‘+’ with respect to primitive data type.
l  Operators can be defined in the class just like any other member function.
l  To make operator as a valid function name we use keyword operator.
l  The following example illustrates definition of ‘+’:

#include<iostream.h>
class complex
{
     private:
            int a,b;
     public:
            void getdata();
            void showdata();        
            complex operator +(complex);
};
complex complex :: operator +(complex c)
{
  complex temp;
  temp.a=a+c.a;
  temp.b=b+c.b;
  return(temp);
}
void complex:: getdata()
{
            cout<<”Enter two numbers”;
            cin>>a>>b;
}
void complex:: showdata()
{
            cout<<”a=”<<a<<”b=”<<b;
}
void main()
{
  complex c1,c2,c3;
  c1.getdata();
  c2.getdata();
  c3=c1+c2; 
  c3.show();
}

l  In this example observe the line c3=c1+c2;
l  Here, c1 calls member ‘+’ and pass c2 as a parameter. The value of c2 will be copied to object c.
l  Read carefully the code of member ‘+’ in class complex.
l  Object c contains the same data as object c2 contains in main().
l  As c1 is used to call operator ‘+’, variables a and b mentioned in the body of ‘+’ are of object c1.
l  Addition of data of objects are then stored in a temporary object temp;
l  The value stored in temp is then returned to main(), which is received in object c3.
l  Original meaning of operator ‘+’ with respect to primitive data types is preserved.
l  Now we have multiple meanings of operator ‘+’. Compiler will resolve the version of ‘+’ by type of operands.
l  Same operator has now multiple jobs, this is known as operator overloading.

List of operators that can not be overloaded
There are few operators that can not be overloaded. They are:

l  Conditional operator-   ?:
l  Dereference operator-  *.
l  Dot operator-                .
l  Size of operator-          sizeof()
l  Preprocessor directive-  # and ##
                 
There are few more examples that illustrate overloading of various operators:
Overload unary minus (-)
#include<iostream.h>
class complex
{
     private:
            int a,b;
     public:
            void getdata();
            void showdata();        
            complex operator -();
};
complex complex ::operator –()
{
  complex temp;
  temp.a = -a;
  temp.b = -b;
  return(temp);
}
void main()
{
  complex c1, c2;
  c1.getdata();
  c1.show();
  c2= -c1;
  c1.show();
  c2.show();
}

l  Notice that the unary operator doesn’t need any argument.
l  Unary minus is called by c1and hence a and b in definition of unary minus are of c1.
l  Values of a and b of c1 are copied in variables a and b of temp with invert sign (see code in unary minus)
l  The value of temp is returned and received by c2.

Overload relational operator equal to (==)
#include<iostream.h>
class complex
{
     private:
            int a,b;
     public:
            void getdata();
            void showdata();        
            int operator ==(complex);
};
int complex ::operator ==(complex c)
{
  if(a==c.a && b==c.b)
     return(1);
 else
     return(0);
}
void main()
{
  complex c1, c2;
  c1.getdata();
  c2.getdata();
  if(c2==c1)
cout<<”objects are equal”;
 else
            cout<<”objects are not equal”;
}

l  Here, return type of operator is int.
l  If corresponding member variables of both the objects are equal operator returns 1 otherwise 0.
Overload increment operator ++
#include<iostream.h>
class complex
{
     private:
            int a,b;
     public:
            void getdata();
            void showdata();        
            complex operator ++();   //Pre increment
            complex operator ++(int); //Post increment
};
complex complex ::operator ++()
{
   complex temp;
   temp.a= ++a;
   temp.b= ++b;
   return(temp);
}
complex complex ::operator ++(int)
{
   complex temp;
   temp.a= a++;
   temp.b= b++;
   return(temp);
}
void main()
{
  complex c1, c2;
  c1.getdata();
  c2.getdata();
  c3=c1++;  //call to post increment
  c3.show();
  c3=++c2;  //call to pre increment
  c3.show();
}


l  Here, we overload two versions of increment operator. One with no argument is pre-increment and other one with one argument is post increment.
l  Remember, in post increment argument int is mentioned to distinguish between two versions of increment operator. We do not actually pass any integer value during call of post increment.
l  In pre-increment version we increment values of a and b then copy them in variables of temp. Function returns temp which contains incremented values.
l  In post-increment version we copy the values of a and b in variables of temp then increment values of a and b. Function returns temp which contains old values (values before increment). 

No comments:

Post a Comment