Definition

Operator Overloading is a type of polymorphism in which an operator is overloaded to give user defined meaning to it. Overloaded operator is used to perform operation on user-defined data type. For example ‘+’ operator can be overloaded to perform addition on various data types, like for Integer and String etc.

Almost any operator can be overloaded in C++. However there are few operator which can not be overloaded i.e.

  • Scope operator (::)
  • sizeof
  • Member Selector (.)
  • Member Pointer Selector (*)
  • Ternary operator (?:)

Java doesn’t support user-defined operator overloading. The only aspect of Java which comes close to “custom” operator overloading is the handling of + for strings.

C++ does not allow overloaded operators where both arguments are built-in types like int, double, etc. These operator definitions are fixed in the language. At least one of the operator function parameters has to be user-defined data type, but the other one can be of any other type, including a built-in type.

Syntax

Below is the syntax of operator overloading for member function

returnType className  : : operator operatorSymbol(argument_list)  
{
  // function body
}

returnType is the type of value returned by the function, className is the name of the class and operator is the keyword.

// Operator overloading example
class Complex { 
private: 
  int real, imag; 
public: 
  Complex(int r = 0, int i =0)  {
    real = r;
    imag = i;
  } 

  // Called when '+' is used with between two Complex objects 
  Complex operator + (Complex const &obj) { 
    Complex res; 
    res.real = real + obj.real; 
    res.imag = imag + obj.imag; 
    return res; 
  }

  void print() {
    cout << real << " + i" << imag << endl; 
  }
};

int main() 
{
  Complex c1(10, 5), c2(2, 4); 

  // Example call to "operator+" 
  Complex c3 = c1 + c2;
  c3.print(); 
}

Non-Member Operator Overloading

A non-member function operator overloading always appears outside of a class.

Complex operator + (Complex const obj1, Complex const obj2) {
  Complex res; 
  res.real = obj1.real + obj2.real; 
  res.imag = obj1.imag + obj2.imag; 
  return res; 
}

// Calls above operator
Complex obj1;
Complex obj2;
Complex res =  obj1 + obj2;

obj1 + obj2 call to operator+ function that takes two Complex objects as arguments. It returns an object containing the sum, whose values then get copied into res.

At least one of the operator function parameters has to be of user-defined type, but the other one can be of any other type, including a built-in type. For example:

Complex operator + (Complex const obj1, double val) {
  Complex res; 
  res.real = obj1.real + val; 
  res.imag = obj1.imag; 
  return res; 
}

// Calls above operator
Complex res =  obj1 + 4;

Overloading Stream I/O Operators

C++ allows operators to be overloaded by functions that are not members of a class. To provide the overloading of the stream I/O operators the following function could be defined:

ostream& operator<< (ostream& os, Complex x)
{
  os << "Real: " << x.real <<", Imag: " << x.imag;
  return os;
}

// Example showing usage of above function
cout << x;

In above example, first parameter to function operator<<, has to be a reference-type parameter. Because os has to be the very same stream object on which operator are applied to. Inside the function, os is an alias for the original cout object.

The return type has to be a reference to an ostream object, so that each application of << will produce the same ostream object that was originally on the left-hand side, so the next << will take it as its left-hand operand. This is why you can cascade the output operator.

Reference

A Summary of Operator Overloading