Operator overloading allows existing C++ operators such as +, -, *, and [] to be given a specific meaning for user-defined types. It enables objects of classes or structures to be used with operators in a natural and readable way.
- Operator overloading is a form of compile-time polymorphism in C++.
- It allows operators to work with user-defined types while preserving their familiar syntax.
Example: + operator is overloaded to add two Number objects.
#include <iostream>
using namespace std;
struct Number
{
int value;
Number(int v)
{
value = v;
}
// Overload + operator
Number operator+(const Number &n)
{
return Number(value + n.value);
}
void display()
{
cout << value << endl;
}
};
int main()
{
Number n1(5), n2(10);
Number n3 = n1 + n2;
n3.display();
}
Output
15
Explanation: The + operator is overloaded as a member function of Number. When n1 + n2 is used, it calls n1.operator+(n2) and returns a new object containing their sum.
Syntax of Operator Overloading
An operator is overloaded by defining a function using the operator keyword followed by the operator symbol.
return_type operator symbol(parameters) {
// function body
}
Types of Operator Overloading
Operators can be classified based on the number of operands they work with.
1. Unary Operator Overloading
Unary operators work with a single operand. Examples include ++, --, !, and unary -.
#include <iostream>
using namespace std;
class Number {
int value;
public:
Number(int v) : value(v) {}
void operator++() {
++value;
}
void display() {
cout << value;
}
};
int main() {
Number n(5);
++n;
n.display();
return 0;
}
Output
6
Explanation: The prefix ++ operator is overloaded to increase the object's value by one.
2. Binary Operator Overloading
Binary operators work with two operands. Examples include +, -, *, /, and ==.
#include <iostream>
using namespace std;
class Number {
int value;
public:
Number(int v) : value(v) {}
Number operator+(const Number& n) {
return Number(value + n.value);
}
void display() {
cout << value;
}
};
int main() {
Number n1(5), n2(10);
Number n3 = n1 + n2;
n3.display();
return 0;
}
Output
15
Explanation: The overloaded + operator takes two Number objects and returns a new object containing the sum of their values.
Member and Non-Member Operator Functions
An operator can generally be overloaded using a member function or a non-member function.
| Feature | Member Function | Non-Member Function |
|---|---|---|
| Definition | Defined inside the class | Defined outside the class |
| Left Operand | Usually the calling object | Passed as an argument |
| Private Access | Direct access | Requires friendship when needed |
| Example | a.operator+(b) | operator+(a, b) |
A non-member operator function can be declared as a friend when it needs access to private or protected members.
Operators That Can Be Overloaded
Most C++ operators can be overloaded for user-defined types, including:
- Arithmetic: +, -, *, /, %
- Relational: ==, !=, <, >, <=, >=
- Logical: &&, ||, !
- Bitwise: &, |, ^, ~, <<, >>
- Assignment: =, +=, -=, *=, /=
- Increment/Decrement: ++, --
- Other: [], (), ->, ->*, new, delete
Operators That Cannot Be Overloaded
Some operators have fixed language-level behavior and cannot be customized through operator overloading.
- Scope resolution: ::
- Member access: .
- Pointer-to-member access: .*
- Conditional operator: ?:
- Size-of operator: sizeof
- Runtime type information operator: typeid
Reasons These Operators Cannot Be Overloaded
These operators are closely tied to fundamental C++ language operations and therefore have fixed semantics.
- :: Operator: Resolves names such as classes, namespaces, and global variables.
- . and .* Operators: Provide built-in member and pointer-to-member access.
- ?: Operator: Provides conditional evaluation with language-defined behavior.
- sizeof Operator: Determines the size of a type or object as part of the language's type system.
- typeid Operator: Provides runtime type information with behavior defined by the C++ language.
Rules of Operator Overloading
Operator overloading follows several restrictions defined by C++.
- At least one operand must be a user-defined type.
- New operators cannot be created.
- Operator precedence and associativity cannot be changed.
- The number of operands required by an operator cannot be changed.
- Operators cannot be overloaded only for built-in types.
- Some operators can only be overloaded as member functions.
Operator Functions vs Normal Functions
Feature | Operator Function | Normal Function |
|---|---|---|
Syntax | Uses operator keyword | Standard function name |
Invocation | Triggered by using an operator | Called explicitly by name |
Purpose | Redefines behavior of operators | Performs defined actions |
Example | operator+() | add() |