Operator Overloading in C++
Overview
Operator overloading modifies how operators work for a particular user-defined data type (structures or objects). Most of the built-in operators of C++ can be overloaded. This article will use many examples to show the operator overloading procedure.
Types of Overloading in C++
Overloading in C++ can be broadly classified into two types -
- Function Overloading - When we have two functions with the same name but with a different number or/and type of arguments in the code, it is known as function overloading in C++.
- Operator Overloading - It is a compile-time polymorphism using which a special meaning can be provided to an operator for a given user-defined data type.
What are Operators in C++?
In every programming language, along with C++, the operator is the symbol that helps to perform mathematical and logical computations on a value or/and a variable. In other words, we can say that the "Operator operates operands". In C++, we have several types of operators -
- Arithmetic Operators:
- Assignment Operators:
- Relational Operators:
- Logical Operators:
- Bitwise Operators: ,
- Other Operators:
What is Operator Overloading in C++?
We can easily apply operators on primitive data types (like integers, characters, and floating point numbers) but not on user-defined data types like Complex numbers, fractions, etc. We can also make operators work for user-defined data types by explicitly defining the operation performed by a given operator on a given data type, known as Operator overloading in C++.
C++ Syntax for Operator Overloading
Operator Overloading in Unary operators
First, let's understand what the unary operators are. As the name suggests, unary operators work on a single operand like Increment (++), Decrement (\-\-), logical not (!).
Here is an example showing the overloading of unary operators for a class Rectangle.
Output -
Explanation The above is a simple program demonstrating the overloading of unary operators ++ and --. For the ++ operator, we are increasing the length and width by 1, while for the -- operator, we are decreasing both by 1.
Difference between Operator Functions and Normal Functions
Operator functions and normal functions share many similarities. The only difference between the two is that the operator symbol is written in operator functions in place of the function name in normal functions.
Let us understand this through an example -
Can We Overload, All Operators?
Almost all the operators can be overloaded except a few. The following operators are prohibited from being overloaded in C++
- (dot operator)
- (Scope resolution operator)
- (Ternary operator)
There is no fundamental reason to disallow overloading of ?: Bjarne Stroustrup (Creator of C++) just didn't see the need to introduce the special case of overloading a ternary operator. For more detailed insights, please visit this.
Overloadable/Non-overloadable Operators
The following operators can be overloaded -
+ | - | * | / | % | ^ |
---|---|---|---|---|---|
& | | | ~ | ! | , | = |
< | > | <= | >= | ++ | -- |
<< | >> | == | != | && | || |
+= | -= | /= | %= | ^= | &= |
|= | *= | <<= | >>= | [ ] | () |
-> | ->* | new | new [ ] | delete | delete [ ] |
Following operators can't be overloaded -
:: | sizeof | ?: | . |
---|
Canonical Implementations
Though, there are no restrictions on how you implement the function inside. But in general practice, it is expected that any given operator behaves as similarly as possible to its natural task.
For example, an overloaded addition operator is expected to do the addition rather than multiply the operands. Also, the related operators should behave similarly (operators - and -= should do the same subtraction-like operation). The below-given code is the typical/expected/canonical implementation of the assignment operator, which checks the condition of the self-assignment and returns the reference.
Operator Overloading Examples
Example 1 - (Adding and Multiplying Fractions)
Output-
Explanation Here, we have implemented a Fraction class that performs basic arithmetic operations on fractions. We will multiply two numerators and the two denominators for multiplying two fractions. But since we also would like them to be in a simple form, we will divide both of them by their GCD(Greatest Common Divisor).
Example 2 - (Comparing Squares)
Output -
Explanation In the above program, we have overloaded the < and > operators to demonstrate the comparison of two square objects. In both, we are just comparing the areas of two squares and returning true or false.
Advantages and Disadvantages of Operator Overloading
Advantages
- Operator overloading in C++ allows users to use notation closer to the target domain. For example, we can add two complex numbers by writing CN1 + CN2 instead of writing CN1.add(CN2) provided add function is defined in the class.
- Similar syntax, like built-in data types, can also be provided to user-defined data types.
- It makes the program easier to understand for other people, especially in a larger code base.
Disadvantages
- New operators can't be overloaded. Only pre-existing operators can be overloaded.
- Precedence order of the operators can not be changed.
- Arity of the operators can not be changed. For example, we can not do for any particular data type.
Overloading Special Operators
The following operators are known as special operators -
- new - Used to allocate the memory dynamically.
- delete - Used to free the memory dynamically.
- [] and () - Subscript operators
- -> - Member access operators.
Here is an example showing the overloading of the () operator.
Output-
Explanation In the above program, we have implemented a Matrix class where we have provided functions to set the values and print the matrix. We have overloaded the () operator so that we can refer to any cell of the matrix by using the notation mat(i, j), and obviously, we want to access the (i, j)th cell of the matrix.
Conclusion
- Overloading operators in C++ or any other programming language can largely impact the readability of the code.
- Almost all of the operators can be overloaded in C++.
- Operator overloading can only define the operation of an operator, but it can't change its precedence.