0% found this document useful (0 votes)
9 views15 pages

C++ Operator Overloading Explained

This document covers the concept of operator overloading in C++, explaining its significance, syntax, and rules. It details various types of operators that can and cannot be overloaded, along with examples for overloading unary, binary, assignment, and relational operators. The document also discusses the difference between member and non-member functions in operator overloading and provides references for further reading.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views15 pages

C++ Operator Overloading Explained

This document covers the concept of operator overloading in C++, explaining its significance, syntax, and rules. It details various types of operators that can and cannot be overloaded, along with examples for overloading unary, binary, assignment, and relational operators. The document also discusses the difference between member and non-member functions in operator overloading and provides references for further reading.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Paper Code: CIC-211

Subject: Object-Oriented Programming Using C++

Unit02, Lecture 07:

Topics Covered: Operator Overloading in C++


Operator Overloading in C++

1. What is Operator Overloading?


2. Syntax and Rules of Operator Overloading
3. Types of Operators that Can Be Overloaded
4. Operators That Cannot Be Overloaded
5. Overloading Unary Operators
6. Overloading Binary Operators
7. Overloading Assignment Operator
8. Overloading Relational Operators
9. Overloading Stream Insertion (<<) and Extraction (>>) Operators
10. Member vs Non-member Functions in Operator Overloading

1. What is Operator Overloading?

Operator overloading is a feature in C++ that-

 Allows developers to redefine the behavior of existing operators (like +, -, *, =, etc.) for
user-defined types (classes or structs).
 This allows for more intuitive and readable code when working with complex objects, by
using operators in ways similar to their usage with built-in types.
 Means, by overloading operators, you can make them work with your custom objects just
like they do with built-in types (e.g., int, float, etc.).

Why Operator Overloading?

In C++, operators like +, -, *, = already work with built-in data types, but when you define your
own classes, these operators won't work unless you define their behavior. For example, if you have
a Complex number class, you can't directly add two Complex objects with + unless you overload
the + operator.
2. Syntax and Rules of Operator Overloading

The syntax for overloading an operator in C++ is:

return_type operator symbol (arguments) {


// code to define the operation
}

Example: 1 +(operator) Overload, Adding two Complex Number

#include <iostream>
using namespace std;

// Define a class for complex numbers


class Complex {
private:
float real;
float imag;

public:
// Constructor
Complex(float r = 0, float i = 0) : real(r), imag(i) {}

// Overload the + operator


Complex operator + (const Complex& obj) {
Complex temp;
[Link] = this->real + [Link];
[Link] = this->imag + [Link];
return temp;
}

// Function to display the complex number


void display() const {
cout << real << " + " << imag << "i" << endl;
}
};

int main() {
// Create two Complex objects
Complex c1(3.5, 2.5);
Complex c2(1.5, 4.5);
// Add them using the overloaded + operator
Complex c3 = c1 + c2;

// Display the result


[Link](); // Output: 5.0 + 7.0i

return 0;
}

3. Types of Operators that Can Be Overloaded

Category Operators
Arithmetic Operators +, -, *, /, %
Relational (Comparison) Operators ==, !=, <, >, <=, >=
Logical Operators &&, `, !`
Bitwise Operators &, `, ^, ~, <<, >>`
Assignment Operators =
+=, -=, *=, /=, %=, &=, `=, ^=, <<=,
Compound Assignment Operators
>>=`
Unary Operators +, -, *, &, ++, --
Subscript Operator []
Function Call Operator ()
Dereference Operator *
Address-of Operator &
Member Access Operators ->, ->*
Allocation/Deallocation Operators new, new[], delete, delete[]
Comma Operator ,
Type Conversion Operators explicit operator Type()

4. Operators That Cannot Be Overloaded

Operators Reason
:: (Scope Resolution) Used to access namespaces, static members, etc.

. (Member Access) Used to directly access members of a class.

.* (Pointer-to-Member) Used with member pointers (overload ->* instead).


?: (Ternary Conditional) Used for conditional expressions (condition ? expr1 : expr2).
5. Overloading Unary Operators

a. Method I

#include <iostream>

using namespace std;

class Number {

private:

int value;

public:

// Constructor

Number(int v = 0) : value(v) {}

// Unary minus implementation in the form of binary-like function

Number operator-(const Number& obj) {

return Number(-[Link]); // Negates the value of the passed object

// Function to display the value

void display() const {

cout << "Value: " << value << endl;

};

int main() {

Number n1(10);
// Calling operator- as a unary minus by passing the object itself

Number n2 = [Link]-(n1); // Pass n1 to the function

cout << "Unary negation using binary-like form: ";

[Link]();

return 0;

b. Method II

#include <iostream>
using namespace std;
class Counter {
private:
int count; // Data member to hold the count value
public:
// Constructor
Counter() : count(0) {}
// Overload Prefix ++ Operator (e.g., ++obj)
Counter& operator++() {
++count; // Increment the count
return *this; // Return the current object (this is for chaining purposes)
}
// Overload Postfix ++ Operator (e.g., obj++)
Counter operator++(int) {
Counter temp = *this; // Save the current state of the object
count++; // Increment the count
return temp; // Return the saved state (before increment)
}
// Method to display the current count value
void display() {
cout << "Count: " << count << endl;
}
};

int main() {
Counter c;
cout << "Initial count:" << endl;
[Link](); // Display initial count
// Prefix Increment (++c)
++c;
cout << "After Prefix Increment (++c):" << endl;
[Link]();
// Postfix Increment (c++)
c++;
cout << "After Postfix Increment (c++):" << endl;
[Link]();
return 0;
}

6. Overloading Binary Operators

Please refer to section 2 above, overloading of binary operator +

7. Overloading Assignment Operator

Method 1: copy constructor

// Online C++ compiler to run C++ program online

#include <iostream>

using namespace std;

class MyClass {

private:

int value; // Simple integer attribute

public:

// Constructor

MyClass(int v = 0) : value(v) {}

// Copy constructor

MyClass(const MyClass& other_obj) {

value = other_obj.value; // Copy the value from the other object

}
// Function to display the value

void display() const {

cout << "Value: " << value << endl;

};

int main() {

MyClass obj1(10); // Create an obj1 with value 10

MyClass obj2; // Create an obj2 with value 0

obj2 = obj1; // Use the copy constructor to create obj2 as a copy of obj1

// Display the values after copy construction

cout << "After copy construction:" << endl;

[Link](); // Output: Value: 10

[Link](); // Output: Value: 10

return 0;

Method 2: using = overload

#include <iostream>

using namespace std;

class MyClass {

private:

int value; // Simple integer attribute


public:

// Constructor

MyClass(int v = 0) : value(v) {}

// Overloading the assignment operator

MyClass& operator=(const MyClass& other_obj) {


// Step 1: Self-assignment check
if (this != &other_obj) {
// Step 2: Copy value from the source object
value = other_obj.value;
}
// Step 3: Return *this to allow chaining
return *this;
}
// Function to display the value

void display() const {

cout << "Value: " << value << endl;

};

int main() {

MyClass obj1(10); // Create an object with value 10

MyClass obj2; // Create another object with default value 0

// Display initial values

cout << "Initial values:" << endl;

[Link](); // Output: Value: 10

[Link](); // Output: Value: 0


// Use overloaded assignment operator

obj2 = obj1;

// Display values after assignment

cout << "After assignment:" << endl;

[Link](); // Output: Value: 10

[Link](); // Output: Value: 10

return 0;

8. Overloading Relational Operators

#include <iostream>
#include <cmath> // For sqrt() function

class Point {
private:
int x, y;

public:
// Constructor to initialize point
Point(int x_val = 0, int y_val = 0) : x(x_val), y(y_val) {}

// Overload the == operator (as a member function)


bool operator==(const Point& other) const {
return (x == other.x && y == other.y);
}

// Overload the < operator (as a member function)


bool operator<(const Point& other) const {
return (sqrt(x*x + y*y) < sqrt(other.x*other.x + other.y*other.y));
}

// Display function to print point coordinates


void display() const {
std::cout << "(" << x << ", " << y << ")";
}
};

int main() {
Point p1(3, 4); // Point with coordinates (3, 4)
Point p2(6, 8); // Point with coordinates (6, 8)
Point p3(3, 4); // Another point with coordinates (3, 4)

std::cout << "Comparing two points p1 and p2:" << std::endl;

// Overloaded == operator
if (p1 == p2) {
std::cout << "p1 is equal to p2" << std::endl;
} else {
std::cout << "p1 is not equal to p2" << std::endl;
}

// Overloaded < operator


if (p1 < p2) {
std::cout << "p1 is closer to the origin than p2" << std::endl;
} else {
std::cout << "p1 is farther from the origin than or equal to p2" << std::endl;
}

std::cout << "\nComparing two points p1 and p3:" << std::endl;

// Overloaded == operator
if (p1 == p3) {
std::cout << "p1 is equal to p3" << std::endl;
} else {
std::cout << "p1 is not equal to p3" << std::endl;
}

return 0;
}
Using Friend Function:

#include <iostream>
#include <cmath> // For sqrt() function

class Point {
private:
int x, y;

public:
// Constructor to initialize point
Point(int x_val = 0, int y_val = 0) : x(x_val), y(y_val) {}

// Friend function to overload the == operator


friend bool operator==(const Point& p1, const Point& p2);

// Friend function to overload the < operator


friend bool operator<(const Point& p1, const Point& p2);
// Display function to print point coordinates
void display() const {
std::cout << "(" << x << ", " << y << ")";
}
};

// Overloading the == operator as a friend function


bool operator==(const Point& p1, const Point& p2) {
return (p1.x == p2.x && p1.y == p2.y);
}

// Overloading the < operator as a friend function (comparison by distance from


origin)
bool operator<(const Point& p1, const Point& p2) {
double distance1 = sqrt(p1.x * p1.x + p1.y * p1.y); // Distance of p1 from origin
double distance2 = sqrt(p2.x * p2.x + p2.y * p2.y); // Distance of p2 from origin
return distance1 < distance2;
}

int main() {
Point p1(3, 4); // Point with coordinates (3, 4)
Point p2(6, 8); // Point with coordinates (6, 8)
Point p3(3, 4); // Another point with coordinates (3, 4)

std::cout << "Comparing two points p1 and p2:" << std::endl;


// Overloaded == operator
if (p1 == p2) {
std::cout << "p1 is equal to p2" << std::endl;
} else {
std::cout << "p1 is not equal to p2" << std::endl;
}

// Overloaded < operator


if (p1 < p2) {
std::cout << "p1 is closer to the origin than p2" << std::endl;
} else {
std::cout << "p1 is farther from the origin than or equal to p2" << std::endl;
}

std::cout << "\nComparing two points p1 and p3:" << std::endl;

// Overloaded == operator
if (p1 == p3) {
std::cout << "p1 is equal to p3" << std::endl;
} else {
std::cout << "p1 is not equal to p3" << std::endl;
}

return 0;
}

9. Overloading Stream Insertion (<<) and Extraction (>>) Operators

- Make an example by your self (to do)

10. Member vs Non-member Functions in Operator Overloading

A. Member function:

 The operator function is defined as a member of the class. It implicitly takes the left-hand
operand as the calling object (this pointer).
 Only the right-hand operand needs to be passed as an argument.

B. Non-member function:

 The operator function is defined outside the class, typically as a friend function to allow
access to private members.
 Both left and right operands must be passed as arguments.
Example program to demonstrate both:

#include <iostream>

using namespace std;

class Complex {

private:

int real;

int imag;

public:

// Constructor

Complex(int r = 0, int i = 0) : real(r), imag(i) {}

// Member function to overload + (for adding complex numbers)

Complex operator+(const Complex& obj) {

Complex temp;

[Link] = real + [Link];

[Link] = imag + [Link];

return temp;

// Friend function to overload * (for multiplying complex numbers)

friend Complex operator*(const Complex& obj1, const Complex& obj2);


// Function to display the complex number

void display() {

cout << real << " + " << imag << "i" << endl;

};

// Non-member function to overload * (for multiplying complex numbers)

Complex operator*(const Complex& obj1, const Complex& obj2) {

Complex temp;

[Link] = ([Link] * [Link]) - ([Link] * [Link]);

[Link] = ([Link] * [Link]) + ([Link] * [Link]);

return temp;

int main() {

Complex c1(3, 2), c2(1, 7);

// Using the member function to add complex numbers

Complex c3 = c1 + c2;

cout << "Sum: ";

[Link]();
// Using the non-member (friend) function to multiply complex numbers

Complex c4 = c1 * c2;

cout << "Product: ";

[Link]();

return 0;

References:-

Online

1. Tutorialspoint OOP Tutorial: Comprehensive tutorials on OOP concepts with examples. Link
2. GeeksforGeeks OOP Concepts: Articles and examples on OOP principles and applications. Link
3. [Link]

Book

1. "Object-Oriented Analysis and Design with Applications" by Grady Booch: Classic book covering
fundamental OOP concepts and real-world examples.
2. "Object-Oriented Programming in C++" by Robert Lafore: Detailed guide to OOP in C++, explaining
concepts with a practical example

You might also like