Introduction to Operator Overloading in C++

In this chapter, we’ll learn about a powerful concept of C++ known as operator overloading.

Why do we need operator overloading?

Operator overloading is a powerful feature in C++ that allows developers to define the behavior of operators for user-defined types. It enables objects of a class to work with operators in a way that is intuitive and consistent with the built-in types. By overloading operators, we can provide custom implementations for operations like addition, subtraction, comparison, and more, tailored to our specific class requirements.

Benefits and use cases

The purpose of operator overloading is to enhance the usability and expressiveness of user-defined types. By defining appropriate operator behaviors, we can make our code more concise, readable, and maintainable. Some common use cases for operator overloading include:

  1. Mathematical and arithmetic operations: Overloading operators allow us to perform mathematical operations on objects of our class, making our code more intuitive. For example, we can define addition and subtraction operations for a Vector class.

  2. Custom comparison and equality: We can define custom comparison operators, such as greater than (>) or less than (<), to compare objects based on specific criteria. This is especially useful when dealing with complex data structures.

  3. Input/output operations: By overloading input (>>) and output (<<) operators, we can enable formatted input and output for objects of our class, making it easier to read and write data.

  4. Container classes: Operator overloading is commonly used in container classes like arrays, linked lists, or matrices. It allows us to access elements using the subscript operator ([]) or iterate over the container using iterators.

Fundamental concepts

Before going into the details of operator overloading, it’s important to understand some fundamental concepts.

Understanding operators in C++

Operators in C++ are symbols that represent operations to be performed on operands. Examples of operators include +, -, *, /, and =. They can be classified as unary operators (operating on a single operand) or binary operators (operating on two operands).

The general syntax of outside and inside the class declaration of an operator

To overload an operator, we need to provide a special function called the operator ⊙ () function. Inside the class, the operator ⊙ () function is declared as a member function. Outside the class, the operator ⊙ () function is declared as a nonmember function.

Let's take a look inside the class declaration:

class MyClass {
public:
ReturnType operator ⊙ (Parameters); // where Parameters are the remaining operands other then left
};

And let's look outside of the class declaration:

ReturnType operator ⊙ (Parameters);

In the above general syntax, could be any of the operators in the following list:

  • Unary operators: +, -, *, &, !, ~, ++, --, ()

  • Binary operators:

    • Arithmetic: +, -, * , /, %

    • Assignment: =, +=, -=, =, /=, %=, &=, |=, ^=, <<=, >>=

    • Relational: ==, !=, <, >, <=, >=

    • Logical: &&, ||

    • Indexing [] and generalized: ()

    • Shift or I/O operators <<, >>

    • ->, * (very famous in STL::iterators)

  • Miscellaneous operators: new, delete

Remember: returnType operator ⊙ (paramter list), as a member function of the class has one lesser parameters than the global operator function returnType operator ⊙ (paramter list). This is due to the fact that the leftmost parameter is automatically passed as a this pointer in member functions.

Limitations and restrictions of operator overloading

  • We can’t change the number of parameters of the defined operator. For example, we can’t overload the addition operator (+) to accept three operands.