News & UpdatesProgrammingWeb programming StoreMy Projects
Links
Affiliates

C++ Tutorial – 21 – Operator Overloading

Operator overloading allows operators to be redefined and used where one or both of the operands are of a user-defined class. When done correctly, this can simplify the code and make user-defined types as easy to use as the primitive types.

Operator overloading example

In the example below there is a class called MyNum with an integer field and a constructor for setting that field. The class also has an addition method that adds two MyNum objects together and returns the result as a new object.

class MyNum 
{
 public:
  int val;
  MyNum(int i) : val(i) {}
 
  MyNum add(MyNum &a) 
  { return MyNum( val + a.val ); }
};

Two MyNum instances can be added together using this method.

MyNum a = MyNum(10), b = MyNum(5);
MyNum c = a.add(b);

Binary operator overloading

What operator overloading does is simplify this syntax and thereby provide a more intuitive interface for the class. To convert the add method to an overload for the addition sign, replace the name of the method with the operator keyword followed by the operator that is to be overloaded. The whitespace between the keyword and the operator can optionally be left out.

MyNum operator +(MyNum &a) 
{ return MyNum( val + a.val ); }

Since the class now overloads the addition sign, this operator can be used to perform the calculation needed.

MyNum c = a + b;

Keep in mind that the operator is only an alternative syntax for calling the actual method.

MyNum d = a.operator+(b);

Unary operator overloading

Addition is a binary operator, because it takes two operands. The first operand is the object from which the method is called, and the second operand is that which is passed to the method. When overloading a unary operator, such as prefix increment (++), there is no need for a method parameter since these operators only affect the object from which they are called.

With unary operators, a reference of the same type as the object should always be returned. This is because when using a unary operator on an object, programmers expect the result to return the same object and not just a copy. On the other hand, when using a binary operator, programmers expect a copy of the result to be returned and therefore return by value should be used.

MyNum& operator++() // ++ prefix
{ ++val; return *this; }

Not all unary operators should return by reference. The two postfix operators – post-increment and post-decrement – should instead return by value, because the postfix operations are expected to return the state of the object before the increment or decrement occurs. Note that the postfix operators have an unused int parameter specified. This parameter is used to distinguish them from the prefix operators.

MyNum operator++(int) // postfix ++
{
  MyNum t = MyNum(val); 
  ++val;
  return t; 
}

Overloadable operators

C++ allows overloading of almost all operators in the language. As can be seen in the table below, most operators are of the binary type. Only a couple of them are unary, and some special operators cannot be categorized as either. There are also some operators that cannot be overloaded at all.

Binary operatorsUnary operators
+ – * / %
= += -= *= /= %=
&= ^= |= <<= >>=
== != > < >= <= & | ^ << >> && ||
–> –>* ,
+ – ! ~ & * ++ —
Special operators
( ) [ ] delete new
Not overloadable
. .* :: ?: # ## sizeof
Recommended additional reading:
Sams - Teach Yourself C++ in One Hour a Day