One of the advanced features in Object-Oriented Programming (OOP) is the ability to redefine how operators work for user-defined types. This is called Operator Overloading in C++. It allows objects to interact using intuitive symbols (like +
, -
, ==
, etc.), improving code readability and usability.
In this detailed blog by Kamlesh Singad from Code With Kamlesh, we’ll explore operator overloading in-depth—from theory to real-world implementation—so that learners can understand the concept easily and use it confidently in their projects.
What is Operator Overloading in C++?
Operator Overloading means providing a new meaning to existing operators for user-defined data types (classes and structs). Instead of using member functions with long names, you can use familiar operators to perform operations on objects.
For example, instead of writing:
complex1.add(complex2);
You can write:
complex1 + complex2;
This is possible because of operator overloading.
Also Read: Inline Functions & Function Overloading in C++
Why Use Operator Overloading?
- Improves readability and elegance of code.
- Makes object-oriented code feel more natural and intuitive.
- Allows custom data types to behave like built-in types.
- Enables operator chaining and complex calculations between objects.
Syntax of Operator Overloading
return_type operator op (argument_list) {
// operator body
}
operator
is a keyword.op
is the operator being overloaded.- Can be defined as a member function or friend function.
Which Operators Can Be Overloaded in C++?
Category | Operators |
---|---|
Arithmetic | +, -, *, /, % |
Comparison | ==, !=, <, >, <=, >= |
Assignment | =, +=, -=, *=, /=, %= |
Bitwise | &, |
Unary | ++, –, +, – |
Logical | !, &&, |
Others | [], (), ->, new, delete |
Operators That Cannot Be Overloaded
- Scope resolution
::
- Member access
.
- Ternary
?:
- Sizeof
- Typeid
Types of Operator Overloading
1. Unary Operator Overloading
Overloads operators that work with a single operand.
class Counter {
private:
int value;
public:
Counter() : value(0) {}
void operator++() {
++value;
}
void display() {
cout << "Value: " << value << endl;
}
};
Counter c;
++c;
c.display();
2. Binary Operator Overloading
Overloads operators that work with two operands.
class Complex {
public:
int real, imag;
Complex(int r = 0, int i = 0) {
real = r;
imag = i;
}
Complex operator + (const Complex& obj) {
Complex result;
result.real = real + obj.real;
result.imag = imag + obj.imag;
return result;
}
void display() {
cout << real << " + " << imag << "i" << endl;
}
};
3. Operator Overloading Using Friend Function
class Complex {
private:
int real, imag;
public:
Complex(int r, int i) : real(r), imag(i) {}
friend Complex operator - (const Complex&, const Complex&);
void display() {
cout << real << " + " << imag << "i" << endl;
}
};
Complex operator - (const Complex& c1, const Complex& c2) {
return Complex(c1.real - c2.real, c1.imag - c2.imag);
}
4. Overloading Comparison Operators
class Box {
public:
int length;
Box(int l) : length(l) {}
bool operator > (const Box& b) {
return length > b.length;
}
};
5. Overloading the []
Subscript Operator
class Array {
private:
int arr[10];
public:
int& operator[](int i) {
return arr[i];
}
};
6. Overloading the ()
Function Call Operator
class Functor {
public:
void operator() (string name) {
cout << "Hello, " << name << endl;
}
};
Functor greet;
greet("Kamlesh");
Best Practices for Operator Overloading
- Maintain semantic meaning of operators.
- Avoid overloading operators in non-intuitive ways.
- Always test for edge cases (e.g., zero division).
- Use friend functions when left operand is not an object of the class.
- Avoid overcomplicating code with too many overloaded operators.
Also Read: Recursion in C/C++: Understanding Recursive Functions
Common Mistakes to Avoid
- Forgetting to return object in binary operators.
- Using incorrect return types (e.g., returning
void
for+
operator). - Overloading operators that shouldn’t be (e.g., logical operators with side effects).
- Breaking associativity or precedence rules.
- Ignoring
const
correctness.
Also Read: Functions in C/C++: Declaration, Definition, and Calling
Real-World Example: Matrix Addition Using Operator Overloading
class Matrix {
private:
int a[2][2];
public:
void setValues() {
cout << "Enter 4 values: ";
for(int i=0; i<2; ++i)
for(int j=0; j<2; ++j)
cin >> a[i][j];
}
Matrix operator + (Matrix m) {
Matrix temp;
for(int i=0; i<2; ++i)
for(int j=0; j<2; ++j)
temp.a[i][j] = a[i][j] + m.a[i][j];
return temp;
}
void display() {
for(int i=0; i<2; ++i) {
for(int j=0; j<2; ++j)
cout << a[i][j] << " ";
cout << endl;
}
}
};
FAQs
What is operator overloading in C++?
It is a feature that allows predefined operators to be redefined for user-defined types.
Can all operators be overloaded?
No. Some like ::
, .
, and ?:
cannot be overloaded.
When should I use operator overloading?
Use it when it makes your object behave like a natural data type (e.g., +
for Complex numbers).
What is the difference between member and friend function overloading?
Member functions use the calling object as the left operand. Friend functions work when the left operand is not an object.
Can we overload the assignment operator?
Yes, and it’s especially useful when managing dynamic memory in classes.
Conclusion
Operator Overloading in C++ is a powerful tool that helps developers write expressive, clean, and readable code using their own data types. Whether you’re designing a complex mathematical class or just simplifying object interaction, knowing how to overload operators correctly can drastically improve your design.
With the guidance of Kamlesh Singad in the Code With Kamlesh series, you’re now equipped with theoretical knowledge and practical skills to confidently implement operator overloading in C++ programs.