Operator overloading plays a crucial role in C++ programming. This feature enables compile-time polymorphism, allowing developers to redefine the behavior of specific operators like '+', '-', '==', and '*'.
It allows for the utilization of ' + ', ' - ', ' * ' operators with user-defined class objects, enabling operations to be performed with those objects. Various other examples of classes that can have arithmetic operators overloaded include Fractional Numbers, Big Integers, Complex Numbers, and numerous others.
Syntax:
It has the following syntax:
Return_Type classname :: operator symbol(Argument list)
{
//Code to be executed
}// It can be done by declaring the function
In this syntax:
- Return Type: An overloaded operator should always have a return type.
- The Overloaded operator may take one or more parameters.
- Operators can be overridden as member functions or non-member functions (friend functions).
Simple Example Using C++ Operator Overloading:
Example
#include <iostream>
using namespace std; //using standard namespace
class Fract {
private:
int a1;
int b1;
public:
Fract() : a1(0), b1(0) {}
void in() {
cout << "Enter the numerator: ";
cin >> a1;
cout<< "Enter the denominator: ";
cin >> b1;
}
// Overload the * operator
Fract operator * (const Fract &ob) {
Fract tem;
tem.a1 = a1 * ob.a1;
tem.b1 = b1 * ob.b1;
return tem;
}
void out() {
cout<<"The fraction is "<< a1<<"/ "<<b1;
}
};
int main() //main function
{
Fract Fa1, Fa2, res;
cout << "Enter the first fraction:n";
Fa1.in();
cout << "Enter the second fraction:n";
Fa2.in();
// The overloading operator
res = Fa1 * Fa2;
res.out();
return 0;
}
Output:
Enter the first fraction: Enter the numerator : 3
Enter the denominator : 4
Enter the second fraction:nEnter the numerator : 2
Enter the denominator: 5
The fraction is 6/ 20
Explanation:
This C++ program introduces the 'Fract' class, designed to handle fractions, specifically overloading the multiplication operator. Within this class, the attributes 'a1' (representing the numerator) and 'b1' (representing the denominator) are kept private.
The 'operator*' function overloads the multiplication operator to multiply two fractions by multiplying both the numerators and denominators. Within the main function, two fraction objects are instantiated, user input is collected, and the product of the fractions is calculated.
Rules for C++ Operator Overloading:
There are several rules that help to understand operator overloading in C++.
- If we want to use operator overloading, at least one operand should be a user-defined class object.
- We may only enable to overload existing operators. We cannot overload new operators.
- In C++, some of the operators may not be overloaded using the friend function. Although, these operators may be overloaded with the assistance of the member functions.
Types of Operator Overloading in C++:
Various forms of operator overloading include the following:
1. Unary Operator Overloading:
In C++, a unary operator overload function is a form of operator overloading that operates on a single operand.
C++ Unary Operator Overloading Example:
Let's consider a scenario to demonstrate the overloading of unary operators in the C++ programming language.
Example
#include <iostream>
using namespace std; //using standard namespace
class Decrement {
private:
int val;
public:
// the constructor
Decrement(int v) : val(v) {}
// Overload prefix decrement operator (--x)
Decrement operator--() {
--val; // decrement the value
return *this; // return val
}
// Function to display value
void display() {
cout << "The Value: " << val << endl;
}
};
int main() //main function
{
Decrement obj(15); // The object initialization
cout << "The value before decrement: ";
obj.display();
--obj; // the prefix operator overloading
cout << "The value after decrement: ";
obj.display();
return 0;
}
Output:
The value before decrement: The Value: 15
The value after decrement: The Value: 14
Explanation:
The provided C++ code is created to overload the prefix decrement operator (--). Within the Decrement class, there exists a private integer member labeled "val" that is initialized through a constructor. The prefix decrement operator is defined using a member function named operator, responsible for reducing the 'val' value by one and then returning the updated object.
2. Binary Operator Overloading
In the C++ binary operator overloading method, it is essential to have precisely one argument available for passing. This type of operator overloading is responsible for executing operations on a pair of operands.
C++ Binary (+) Operator Overloading Example:
Let's consider an illustration to showcase the Binary (+) Operator Overloading in C++.
Example
#include <iostream>
using namespace std; //using standard namespace
class Cmplx {
float real_num, imag_num;
public:
// Constructor
Cmplx(float r = 0.0, float i = 0.0) : real_num(r), imag_num(i) {}
// Overloading + operator as a member function
Cmplx operator+(const Cmplx& other) {
return Cmplx(real_num + other.real_num, imag_num + other.imag_num);
}
// Display function
void display() const {
cout << real_num << " + " << imag_num << "i" << endl;
}
};
int main() //main function
{
Cmplx a1(4.7, 2.8), a2(3.5, 5.7);
Cmplx a3 = a1 + a2; // Using overloaded + binary operator
cout << "Enter the First Cmplex Number: ";
a1.display();
cout << "Enter the Second Complex Number: ";
a2.display();
cout << "Sum of both Numbers: ";
a3.display();
return 0;
}
Output:
Enter the First Cmplex Number: 4.7 + 2.8i
Enter the Second Complex Number: 3.5 + 5.7i
Sum of both Numbers: 8.2 + 8.5i
Explanation:
In this instance, a sophisticated class was selected, incorporating two private attributes, realnum and imagnum. Subsequently, a constructor with parameters and default values was implemented. This constructor initializes the complex numbers as realnum + imagnum * i. Following this, the binary + operator is utilized within the code to display the total of the two complex numbers.
3. Binary Operator Overloading using a Friend Function:
In C++, when implementing binary operator overloading through a friend function, it is essential that the operator overloading function is defined prior to the friend function. Additionally, this function must be declared within the scope of the class. Typically, in a binary operator scenario, the friend function accepts two distinct parameters and alters one parameter using the unary operator.
In this instance, we will demonstrate an example of overloading binary operators in C++ by utilizing a friend function.
Let's consider an illustration to showcase the Binary Operator Overloading through the utilization of the friend function in C++.
Example
#include <iostream>
using namespace std; //Using Standard Namespace
class Factorial_Of_Number {
int num;
long long fact;
public:
//Using Constructor
Factorial_Of_Number(int n = 1) : num(n) {
fact = 1;
for (int i = 1; i <= num; ++i)
fact *= i;
}
// Friend function
friend Factorial_Of_Number operator*(const Factorial_Of_Number& x, const Factorial_Of_Number& y);
// Display function
void display() const {
cout << "Factorial of " << num << " is: " << fact << endl;
}
// Display product
void displayProduct() const {
cout << "Product of factorials: " << fact << endl;
}
};
// Overloaded * operator using friend function
Factorial_Of_Number operator*(const Factorial_Of_Number& x, const Factorial_Of_Number& y) {
Factorial_Of_Number result;
result.fact = x.fact * y.fact;
result.num = x.num * y.num;
return result;
}
int main() //Main function
{
Factorial_Of_Number x(5);
Factorial_Of_Number y(4);
Factorial_Of_Number result = x * y;
x.display();
y.display();
result.displayProduct();
return 0;
}
Output:
Factorial of 5 is: 120
Factorial of 4 is: 24
Product of factorials: 2880
Explanation:
In this instance, we are outlining a class named FactorialOfNumber, responsible for computing the factorial of a specified numerical value. Subsequently, we shall implement binary operator overloading by employing a friend function to overload the * operator.
When two instances of a class are multiplied, the friend function retrieves their private factorial values, calculates the product of those factorials, and returns a new object containing the result. The show method is responsible for displaying the factorial values, while the showProduct function is used to present the final output.
Which Operators Can and Cannot Be Overloaded in C++?
When it comes to overloading unary and binary operators in C++, it's important to note that not all operators are overloadable, and certain ones must be left unaltered.
Operators that can be overloaded are those that can be redefined to operate with user-defined types, whereas operators that cannot be overloaded are considered fundamental to the language and cannot be redefined.
Here is a list of operators which cannot be overloaded in C++.
- Ternary (Conditional) Operator (? :)
- Member Access (Dot) Operator (.)
- Pointer-to-Member Operator (.*)
- Scope Resolution Operator (::)
- Type Identification Operator (typeid)
- Size Operator (sizeof)
Operator overloading is achievable with specific operators in C++.
Special Operator Overloading in C++:
There are various operators in C++ which can be overloaded for their use in user-defined datatypes. These include the following set of operators.
- new: It is used to declare a pointer variable as well as allocate memory to it when the program is being executed.
- delete: This operator frees up the memory which has been assigned to the pointer variable.
- (subscript): This operator enables the selection of a particular value from an array.
- (member access): It permits the selection of the variable members of the class through a pointer.
- = (assignment): This operator is used to copy data from one object to another object.
- (function call): This operator gives every object the ability to act as a function.
By overloading these operators, it streamlines the structure of interactions among the objects and enhances the effectiveness and adaptability of the C++ programming ecosystem.
Benefits of Operator Overloading in C++:
Several benefits of operator overloading in C++ are as follows:
- Improved Clarity: The programmers will have the chance to use a more comprehensible syntax, which increases clarity and understanding of the code due to operator overloading.
- Increased Maintainability: It allows user-defined types to behave like fundamental types, which reduces issues and provides better maintenance.
- Support for Reuse of Code: The possibility of applying an operator to other different objects increases the support of reusability.
- Abstraction and Encapsulation: Operator overloading is a feature of object-oriented programming and is facilitated by the abstraction and encapsulation of data.
Drawbacks of Operator Overloading in C++:
Several drawbacks of operator overloading in C++ are as follows:
- Potential Misuse: It is possible to define overloaded operators in a way that leads to redundancy or makes the implementation harder to follow.
- Increased Difficulty: Because of the previously defined purpose, overloads may seem to make the application more complex, therefore introducing confusion and additional issues to solve.
- Limits of Overloading: In C++, there is no possibility to overload every operator, for example, member access operators.
Conclusion:
In summary, operator overloading allows customized user-defined data types to mimic predefined types, improving the clarity, versatility, and manageability of code. It permits the customization of operators for specific classes, simplifying the resolution of complex issues.
C++ Operator Overloading MCQs
- Can the assignment (=) operator be overloaded in C++?
- Yes, as a friend function
- Yes, as a Member Function
- Yes, but only as a non-member function
- Which operators are obligated to be overloaded as class member functions in C++?
- Which of the following statements is correct about the friend function operator in C++?
- They must be defined in the class
- They can access the private members of a class
- They are slower than the member functions
- They can only overload unary operators
- What is the purpose of overloading the following operator function?
Bool operator== (const MyClass &obj);
- Equality Comparison
- Addition
- Assignment
- Logical AND
a) Comparing Equality
- Which operators in C++ are eligible for overloading?
- sizeof