Operator overloading in C++ is done by programmers to redefine the standard operators without changing their original meaning, which enhances code reusability, readability, and efficiency. Also, it helps in performing operations on complex numbers and custom memory management.
In this article, we will discuss operator overloading in C++, types of overloading in C++, the difference between function overloading and operator overloading, rules and idioms for the operator overloading, operators that can be overloaded and that cannot be, binary and unary operator overloading, advantages and disadvantages of operator overloading, and important points to remember about the operator overloading in C++.
Table of Contents:
What is Operator Overloading in C++
Operator overloading in C++ is a basic feature that helps programmers define custom behavior for the operators when they are used with user-defined data types such as classes and structures. It helps the programmers by enabling objects to be manipulated by using the standard operators just as the built-in data types.
Why Use Operator Overloading in C++?
Below are a few reasons why operator overloading in C++ can be used:
- Operator overloading in C++ improves performance, code readability, and usability.
- It allows custom data types to behave like the built-in data types in C++.
- It also helps to simplify the complex expressions with the user-defined objects.
Syntax of Operator Overloading in C++
return_type ClassName::operator op (parameter_list) {
// Operator overloading implementation
}
Example:
Output:
The code shows the operator overloading in C++, as the + operator is redefined to add two Complex objects by using the overloaded operator + function.
Types of Overloading in C++
There are two types of overloading in C++:
- Function Overloading
- Operator Overloading
Function Overloading in C++
Function overloading in C++ allows multiple functions to have the same name but different parameters, and the compiler determines which function should be called based on the number and types of arguments.
Example:
Output:
The code shows the function overloading in C++, as in the code, there are multiple add functions with the same name but different parameters, and the compiler will select the function that will be passed to the function calls based on the number and types of arguments.
Note: We have already discussed operator overloading in C++ above, so please refer to that.
Difference Between Function Overloading and Operator Overloading in C++
Feature |
Function Overloading | Operator Overloading |
Definition | Defining multiple functions with the same name but different parameter lists. | Redefining the behavior of operators (+, -, *, etc.) for user-defined types. |
Purpose | Improves code readability by using the same function name for different tasks. | Allows operators to work with objects of custom classes. |
Usage | Used to perform different operations using the same function name but with different arguments. | Used to perform operations on user-defined types (objects) using standard operators. |
Syntax | int add(int a, int b); double add(double a, double b); | Complex operator+(const Complex &c); |
Implementation | Implemented by defining multiple functions with the same name but different parameter lists. | Implemented by defining an operator function inside or outside the class. |
Return Type | The return type does not differentiate overloaded functions. | The return type can be different depending on the operator. |
Works on | Only on functions. | Both unary (++, –, !) and binary (+, -, *, /, ==) operators. |
Friend Function Usage | Not required. | Can use friend functions for non-member overloading. |
Can All Operators Be Overloaded in C++?
No, all operators cannot be overloaded in C++, but we can also say that almost all operators can be overloaded only a few are there that cannot be overloaded.
Operators That Cannot Be Overloaded in C++
Below is a list of operators that cannot be overloaded in C++:
Operator |
Description |
:: (Scope Resolution) | Accesses namespaces and class members. |
. (Member Access) | Directly accesses object members. |
.* (Pointer-to-Member) | Used with pointers to class members. |
?: (Ternary Operator) | Conditional (if-else) operator. |
sizeof | Returns the size of a type or variable. |
typeid | Used for runtime type identification. |
alignof | Determines memory alignment requirements. |
co_await | Used in coroutines for asynchronous programming. |
Operators That Can Be Overloaded in C++
Below is a list of operators that can be overloaded in C++:y
Category of Operators | Operators |
Arithmetic Operators | +, -, *, /, % |
Relational (Comparison) Operators | ==, !=, <, >, <=, >= |
Logical Operators | && |
Bitwise Operators | & |
Assignment Operators | =, +=, -=, *=, /=, %=, &=, | |
Increment and Decrement Operators | ++, — |
Subscript Operator | [] |
Function Call Operator | () |
Pointer Operators | * (dereference), -> (member access) |
Stream Insertion and Extraction Operators | <<, >> |
Why Can’t Certain Operators Be Overloaded in C++?
Below are the reasons why the operators cannot be overloaded in C++:
1. [::] (Scope Resolution) – Scope resolution is used to access the namespace and class members, and redefining it will break the basic C++ syntax.
2. [ . ](Member Access) – It directly accesses the object members, and overloading it would interfere with the member access rules.
3. [.* ](Pointer-to-Member) – It is used to access the class members through the pointers, and if you try to change it, then it would disrupt the behavior of the pointer.
4. [?:] (Ternary Operator) – The ternary operator is used for the complex evaluation order, and overloading it would change the conditional expressions.
5. sizeof – The sizeof operator is used to determine the size of the object, which is evaluated at compile time. So, it cannot be changed to work at runtime.
6. typeid – It is used for runtime type identification (RTTI), and thus, overloading it would break the built-in type checking.
Rules and Idioms for Operator Overloading in C++
To make sure that there is clear and maintainable operator overloading in C++, the basic rules and idioms must be followed. These are the operator’s precedence and associativity, or the number of operands, which cannot be changed and can only be overloaded by existing operators.
Binary Operator Overloading in C++
Binary operator overloading in C++ allows the user-defined classes to redefine the behavior of the binary operators when they are used with the objects. Also, a binary operator operates on two operands, which makes it different from a unary operator.
A binary operator can be overloaded in two ways:
1. It can be overloaded as a member function when the left operand is an object of the class.
Example:
Output:
The code shows how the binary operator * is overloaded as a member function to perform the matrix multiplication on the Matrix objects, which computes the product of two 2*2 matrices and prints the result to the console.
2. It can be overloaded as a friend function when the left operand is not an object of the class.
Example:
Output:
The code shows how the binary operator + is overloaded using a friend function in the C++ program to add two Complex numbers and print the result to the console.
Overloading Unary Operators in C++
Unary operator overloading in C++ allows the user to change the behavior of a single operand operator for the user-defined data types. A unary operator can be overloaded using the member functions since it works on a single object.
Example:
Output:
The code shows how the unary operator – is overloaded in C++ to negate the value of a Number object, which returns a new object with the negated value, and then the values are printed to the console.
Overloading Special Operators in C++
Below are a few operators that can be overloaded, other than the relational and arithmetic operators:
1. Overloading the [ ] (Subscript Operator)
The subscript operator in C++ is overloaded to provide custom behavior as an array, and it must be implemented as a member function.
Example:
Output:
The code shows how the subscript operator is overloaded to provide the custom behavior as an array to access the elements and changes with the bound checking.
2. Overloading the () (Function Call Operator)
Overloading the function call operator allows objects to be used as a function in a C++ program.
Example:
Output:
The code shows how the function call ( ) operator is overloaded to allow the Multiplier object to be used as a function to multiply two numbers, 5 and 4, and then the result is printed to the console.
3. Overloading the -> (Arrow Operator)
The arrow operator in C++ is overloaded to return a pointer to an object for a smart pointer.
Example:
Output:
The code shows how the arrow -> operator is overloaded to allow a SmartPointer object to access the Test class functions, such as the raw pointer.
4. Overloading new and delete Operators
The new and delete operators in C++ are overloaded globally for debugging, logging, and customized memory management.
Example:
Output:
The code shows how the new and delete operators are overloaded in a C++ program to display custom messages when there is dynamic memory allocation and deallocation.
Advantages of Operator Overloading in C++
- The operator overloading in C++ improves the code readability by allowing operators to work with user-defined data types.
- It provides custom object behavior, which helps in operations such as matrix multiplication and complex number addition.
- It improves the code reusability as the overloaded operators can be reused in different classes and reduces redundant function calls.
- Operator overloading supports the user-defined data types and maintains consistency with the built-in types.
- It is also important to enable the smart pointers for the custom memory management.
Disadvantages of Operator Overloading in C++
- Overloading multiple operators increases the code complexity because the code becomes harder to read and maintain.
- The overloaded operators that have function calls give a slight performance overhead.
- If the overloading is not done properly, then the overloaded operators will behave unexpectedly.
- All operators cannot be overloaded thus, it limits the customization of operators.
- It is very difficult to find the errors in the overloaded operators as they work implicitly in the expressions.
Important Points to Remember About Operator Overloading in C++
- You can only overload the already existing operators.
- You cannot change the operator’s precedence and associativity by overloading it.
- All operators cannot be overloaded.
- The overloaded operators have at least one operand that must be a user-defined type.
- Operators can be overloaded as member and non-member functions.
- Also, you cannot overload the operators for the standard data types such as int, float, etc.
- The operators = and & are by default overloaded in C++.
Conclusion
The operator overloading in C++ helps to code readability, usability, and maintainability by allowing user-defined data types to behave as built-in data types. Also, it helps to simplify the various operations and must not be used unnecessarily. So, by understanding operator overloading with its advantages and disadvantages, you can easily overload the operators in C++ without any confusion or error.
FAQs on Operator Overloading in C++
Q1. What is operator overloading?
The operator overloading is redefining the standard operators for the user-defined types.
Q2. Why is operator overloading useful?
It improves code readability and usability by enabling intuitive operations on objects.
Q3. Can all operators be overloaded?
No, the operators such as ::, ., .*, sizeof, typeid, and ?: cannot be overloaded.
Q4. What are the types of overloading in C++?
There are two types of overloading in C++: function overloading and operator overloading.
Q5. What are the key rules for operator overloading?
The rules for operator overloading are that at least one operand must be a user-defined type, and operator precedence cannot be changed.