Presented by
1
Ayesha Julekha
Lecturer , dept of cse , iiuc
2
Operator overloading is a feature of object-oriented programming that allows
existing operators (like +, -, *, ==, etc.) to be redefined so they can work with user-
defined data types (objects) in a meaningful way.
It enables objects to interact using operators just like built-in types, making the
code more readable, natural, and expressive
3
#include <iostream> Complex operator + (Complex obj) {
using namespace std; Complex result;
[Link] = real + [Link];
class Complex { [Link] = imag + [Link];
public: return result;
int real, imag; }
};
Complex(int r = 0, int i = 0) {
real = r; int main() {
imag = i; Complex c1(2, 3), c2(1, 7);
} Complex c3 = c1 + c2; cout << [Link]
<< " + " << [Link] << "i";
return 0;
}
4
To make user-defined data types act like built-in types→ Allows objects (like
Complex, Matrix, etc.) to use operators such as +, -, *, /, ==, etc.
To increase code readability and simplicity. Expressions like c3 = c1 + c2; are
easier to read and understand than function calls like c3 = [Link](c2);.
To improve program reusability. You can reuse operators for different types of
objects by defining how they behave.
To provide intuitive and natural syntax for objects. Makes object operations look
similar to arithmetic operations on numbers.
To define customized behavior for operators. You can decide how +, -, *, or ==
should work for your class.
To enhance the functionality of existing operators. Operators can be extended to
perform additional or specialized tasks for complex data types.
5
Can be overloaded Cannot be overloaded
+-*/% ::
== != > < >= <= .
`&&
`& ^ ~ << >>`
= and compound assignments (+=, -= etc.) ?:
++ -- typeid
[] () -> ->* new delete All cast operators
6
To perform a deep copy. Ensures each object gets its own copy of data instead of
sharing the same memory.
To handle dynamic memory [Link] problems like double deletion or
dangling pointers when objects manage memory using new or malloc.
To customize copy behavior. Allows you to define exactly how data should be
copied (e.g., copying arrays, files, or complex structures).
To avoid shallow copy issues. The default assignment operator only copies
addresses (pointers), not the data they point to.
To manage resources properly. Useful when objects hold files, sockets, or database
connections that must be duplicated correctly.
7
When a binary operator is overloaded, the left operand is passed implicitly to the
function, and the right operand is passed as an argument.
In normal case,
int a = 5, b = 10;
int c = a + b; The compiler already knows how to add two [Link] when you have
objects, like:
Complex c1, c2, c3;
c3 = c1 + c2; the compiler doesn’t know how to add them . C++ secretly converts it into a
function call like this: c3 = [Link]+(c2);
c1 is the left operand , it calls the function.
c2 is the right operand ,it is passed as an argument. So: The left operand (c1) is passed
implicitly — it becomes the object that runs the function. The right operand (c2) is
passed explicitly — you send it inside the parentheses.
8
When relational and logical operators are overloaded in C++, their main purpose
is to compare objects rather than to create new ones.
Therefore, these operator functions should not return an object of the class, but
instead return a value that represents either true or false.
Traditionally, this value was returned as an integer—0 for false and a nonzero value
for true—so that the result could easily be used in conditional and logical
expressions.
When overload relational or logical operators, they should return true or false (as
int or bool), because their purpose is to compare objects, not to create new ones.
This makes them behave like normal comparison operators and keeps your code
logical and easy to use.
See example 1 – page 156
9
Unary operator overloading means defining how these one-operand operators
should behave when used with objects of a class.
Key points:
Unary operator works on one object.
The operand (object) is passed implicitly to the operator function.
You can overload it as a member function or friend function.
It makes code more natural and easier to read.
Page-157(example)
10
In C++, the increment (++) and decrement (--) operators can appear before or
after a variable or object:
Prefix form: ++obj (increase first, then use)Postfix form: obj++ (use first, then
increase)In early versions of C++, the compiler could not tell these two forms apart
when you overloaded them so both ++obj and obj++ called the same function.
Prefix version:
coord coord::operator++() // no argument
Postfix version:
coord coord::operator++(int notused) // dummy int parameter
11
Counter operator++(int) {
Counter temp = *this;
#include <iostream> count++;
using namespace std; return temp;
}
class Counter {
int count; void show() { cout << "Count = " << count << endl; }
public: };
Counter(int c = 0) { count = c; }
int main() {
// Prefix increment (++obj) Counter c1(5);
Counter operator++() { ++c1; // calls prefix
++count; [Link](); // Count = 6
return *this;
} c1++; // calls postfix
[Link](); // Count = 7
}
12
The minus (-) operator in C++ can be overloaded both as a unary operator (to
change the sign of object values) and as a binary operator (to subtract one object
from another) by defining two separate functions with the same name but different
parameter lists.
The - operator is used both for negation (unary) and subtraction (binary), so we
overload it twice.
The -- operator, on the other hand, is always unary it only decreases a single
object’s value — so it has no binary form to overload.
13
In C++, an operator can be overloaded in two ways:
[Link] a member function
[Link] a friend function
Member function:
The left operand is passed implicitly (using this pointer).The right operand is passed
explicitly as an argument.
Friend function:
It is not part of the [Link] doesn’t have this pointer, so both operands are passed
explicitly to the function
14
#include <iostream> Complex operator+(Complex c1,
Complex c2) {
using namespace std;
Complex temp;
[Link] = [Link] + [Link];
class Complex {
[Link] = [Link] + [Link];
float real, imag;
return temp;
public:
}
Complex(float r = 0, float i = 0) { real = r;
imag = i; }
int main() {
friend Complex operator+(Complex c1, Complex c1(3.2, 4.5), c2(2.8, 3.5), c3;
Complex c2);
c3 = c1 + c2; // calls friend operator+
[Link](); // Output: 6 + 8i
void show() { cout << real << " + " <<
imag << "i" << endl; } }
};
15
A friend function allows an operator to:
Access private and protected members of a class (like a member function does)But act
outside the class.
it doesn’t need to be called by a specific object. That gives it more flexibility, especially
for binary operators.
16
When you are overloading the assignment operator (=)
it must be a member function (because it modifies the calling object).When the
operator only needs to work on the current object (unary operators)
a member function is simpler.
17
The function operator[](int index) defines what happens when you use [index] with
your object.
It returns a reference (int&) so that you can both read and modify elements.
The function can include bounds checking to avoid invalid access.
You can overload it for both const and non-const objects.
Writing MyClass ob[2]; creates multiple objects .it’s not operator overloading.
Overloading the [ ] operator is used when you have one object that internally
stores many values (like an array), and you want to use the [index] syntax to access
them easily.
18
Makes objects act like arrays You can access elements in a class object using
familiar syntax like obj[i], just like arr[i].
Improves readability and simplicity. Instead of writing [Link](i) or [Link](i, value),
you simply write obj[i] = value;.
Provides array-like behavior for user-defined classes Useful for classes such as
Matrix, Vector, String, or Dynamic Array, where you need element access by index.
Allows bounds checking You can add code to check if the index is valid (e.g., not
less than 0 or greater than size-1).
This prevents out-of-range errors , something that normal C++ arrays don’t
[Link] both reading and writing elements
19
#include <iostream> int main() {
using namespace std; MyArray obj;
class MyArray { cout << "Initial values:" << endl;
int arr[5]; // internal fixed-size array for (int i = 0; i < 5; i++)
public: cout << "obj[" << i << "] = " << obj[i] << endl;
MyArray() {
for (int i = 0; i < 5; i++) obj[2] = 999;
arr[i] = i * 10; // store 0, 10, 20, 30, 40 obj[4] = 555;
}
int& operator[](int index) { cout << "\nAfter modification:" << endl;
if (index < 0 || index >= 5) { for (int i = 0; i < 5; i++)
cout << "Error: Index out of range!" << endl; cout << "obj[" << i << "] = " << obj[i] << endl;
exit(0);
} return 0;
return arr[index]; // return reference to element }
}
};
20
Thank You
21