Friday, Jan 19th

Last update12:59:40 PM GMT

Operator Overloading Basics

Write e-mail

C++ tutorial

argaiv1077

Before starting with operator overloading, I will be assuming that the reader is well versed with the concepts of function overloading and knows how we can use the same name for different functions having similar functionalities but differing in the datatype, number or order of parameters they accept.

Operator overloading extends the capabilities of C++ a step ahead of what function overloading does.

Adding two strings str1 and str2 as str1 + str2 instead of using built-in functions like strcpy and strcat, makes the program look intuitively more obvious and clean.

Even though operator overloading helps the programmers in a big way, but nonetheless, it can be admitted here that operator overloading does make class implementations clumsy. Probably, this is the reason why we do not find Operator Overloading in Java. But still, we can use operator overloading easily without bothering about the implementation's complexities.

Let us start with example:

Consider a class Complex that is used to store complex numbers of the form (x + iy) where x and y are the real and imaginary parts of the complex number resp. It also expects to have basic methods for addition and multiplication of the two complex numbers.

Now if we have two complex numbers (1 + 3i) and (4 + 5i).

Complex c1 (1,3);

Complex c2 (4,5);

Now from the programmer’s point of view who wants to add two complex numbers, he would definitely have preferred using something like:

c1 + c2; over the conventional c1.add(c2);

So in order to make the former work we will have to overload the operator “+” so that it works to make the proper addition between the real members and the imaginary ones and also the assignment. The overloading syntax is quite similar to function overloading, the keyword operator followed by the operator we want to overload. Below I give both the implementations: one is the conventional way and the other using Operator Overloading.

class Complex

{
private:
int real;
int imag;
public:
Complex(int re,double im)
{
real = re;
imag = im
};
int GetRealPart ()
{ return real;}
int GetImagPart ()
{ return imag;}
Complex operator+(Complex c); //operator overloading
Complex add (Complex c); //conventional method
}
 
Complex Complex::operator+(Complex cnum)
{
real = real + cnum.GetRealPart();
imag = imag + cnum.GetImagPart();
return *this;
}
 
Complex Complex::add(Complex cnum)
{
real = real + cnum.GetRealPart();
imag = imag + cnum.GetImagPart();
return *this;
}

One thing to note in the above snippet is that, in both the functions in order to access the real and imag part of Complex object passed as parameter to the functions, we had to use the corresponding Getter functions (GetRealPart() and GetImagPart()) to access the private data members of the object which is obvious. If we want to remove this restriction we can make these functions as friend functions of the class Complex as friend function can access the private data of the class to which it is declared as friend of. For details on friend functions you can refer here. In such case the corresponding declaration in the class will change to:

friend Complex operator+(Complex c);

and the definition of the function will now be a bit simpler and clean. But beware: we cannot use this pointer in the friend function since a friend function is not a member of the class in which it is declared and hence a copy of the object will be required in the return statement now

Complex Complex::operator+(Complex cnum)
{
Complex temp;
temp.real = temp.real + cnum.real;
temp.imag = temp.imag + cnum.imag;
return temp;
}

Things to note:

  1. The no.of operands cannot be overridden. That is, a binary operator will alway take two operands and the unary one will take one operand.
  2. The precedence is still maintained even after overloading the operators. That is, multiplication will still be done before addition unless forced. That is if both * and + operators are overloaded. Then in statements like:
    A = B + C * D ; First the logic of overloaded operator * will be evaluated for C and D and then the result will be evaluated with B as the other input to the overloaded + operator; followed by assignment of final result to A.
  3. The operators that cannot be overloaded are:
    :: (scope resolution)
    . (member selection)
    -> (member selection through pointer)
    ?: (conditional operator)

The most prolific use of operator overloading is in STL (Standard Template Library) of C++. We see at numerous places, operator + being overloaded for concatenation of two strings.

Also remember that, in many cases if we overload an operator the exceptional behavior of the operator may not remain intact. Like for boolean operators the short circuit behavior is followed, that is:

if (a && b && c).here if b is false the value of c is never checked. But such a behavior should not be expected by default when the functionality in overloaded operator “&” is executed.

Share this post



Add comment

Please refrain from using slang or abusive language in the comments.
To avoid waiting for your comment to be published after being reviewed, please log in as a registered user.


Security code
Refresh

Web Hosting