- What is Operator overloading in C++?
- What are Operators?
- What are the types of operator overloading?
- Implementing Operator Overloading Examples
- What are the rules for operator overloading in C++?
- Which operators Cannot be overloaded?
- Overloadable/Non-overloadable Operators
- Overloading special operators in C++
- Conclusion
- FAQs
Operator overloading in C++ is a powerful feature that allows you to redefine the behavior of operators for user-defined data types.
In this blog, we delve into the concept of Operator overloading in C++, accompanied by clear examples to illustrate its usage and benefits.
Whether you’re new to programming or seeking to enhance your understanding of C++, this exploration will provide valuable insights into leveraging Operator overloading effectively in your code.
But before that, if you don’t know the difference between C and C++, check out our blog: “Differences and Similarities Between C & C++“.
What is Operator overloading in C++?
c++ operator overloading refers to the practice of redefining the functionality of operators for user-defined data types.
This feature, also known as “operator overriding in C++,” allows you to customize the behavior of operators such as +, -, *, and / to work with objects of your classes, enhancing the flexibility and expressiveness of your code.
Explore the fundamentals of classes in C++.
What are Operators?
Operators in programming languages are symbols or keywords that perform specific operations on operands to produce results.
These operations can include arithmetic operations like addition and subtraction, comparison operations like equal to and not equal to, logical operations like AND and OR, and more. In essence, operators enable you to manipulate data and control the flow of your code.
Also, Explore beginner-friendly Simple C++ Programs to learn the C++ fundamentals.
What are the types of operator overloading?
There are two types of operator overloading:
- Function overloading.
- Operator overloading.
What is function overloading?
The process of having two or more functions with the same name but with different parameters (arguments) is called function overloading. The function is redefined by either using different types of arguments or a different number of arguments. It is only through these differences that a compiler can differentiate between functions.
Learn more about function overloading in C++ with examples and discover practical examples to strengthen your concept of function overloading in C++!
What is Operator overloading?
Operator overloading in C++ program can add special features to the functionality and behavior of already existing operators, such as athematics and other operations.
The mechanism of giving special meaning to an operator is known as operator overloading. For example, we can overload an operator ‘+’ in a class-like string to concatenate two strings by just using +.
Operations that can be performed:
- Arithmetic operations: + – * / %
- Logical operations: && and ||
- Relational operations: == != >= <=
- Pointer operators: & and *
- Memory management operator: new, delete []
Explore the core concepts of C programming with our free Introduction to C course.
Implementing Operator Overloading Examples
Example 1: Let us multiply two fractions using the overloading of the multiplication operator in C++.
// Multiplication of two fractions
#include <iostream>
using namespace std;
class Frac {
private:
int a;
int b;
public:
Frac() : a(0), b(0) {}
void in() {
cout << "Enter the numerator : ";
cin >> a;
cout<< "Enter the denominator : ";
cin >> b;
}
// Overload the * operator
Frac operator * (const Frac &obj) {
Frac temp;
temp.a = a * obj.a;
temp.b = b * obj.b;
return temp;
}
void out() {
cout<<"The fraction is "<< a<<"/ "<<b;
}
};
int main() {
Frac F1, F2, result;
cout << "Enter the first fraction:n";
F1.in();
cout << "Enter the second fraction:n";
F2.in();
// complex1 calls the operator function
// complex2 is passed as an argument to the function
result = F1 * F2;
result.out();
return 0;
}
OutPut
Enter the first fraction:
Enter the numerator : 2
Enter the denominator : 5
Enter the second fraction:
ENter the numerator: 12
Enter the denominator: 7
The fraction is 24/35
Explanation
This code demonstrates Operator overloading in C++ to multiply two fractions. The Frac class defines a fraction with numerator a and denominator b and overloads the * operator to perform the multiplication of fractions.
When executed, the program prompts the user to input two fractions, multiplies them using the overloaded * operator, and prints the result. In the provided output, when the fractions 2/5 and 12/7 are multiplied, the result is correctly calculated as 24/35.
Join the “PG Program in Software Development and Engineering” to strengthen your C++ skills. Connect with experienced industry professionals and mentors and gain hands-on experience with industry-standard practices, preparing you for a successful career in software development.
Example 2: A C++ program to overload a prefix decrement operator
#include <iostrea
}
// Overload the prefix decrement operator
void operator-- () {
a= --a;
b= --b;
}
void out() {
cout<<"The decremented elements of the object are: "<<endl<< a<<" and " <<b;
}
};
int main() {
OverLoad obj;
obj.in();
--obj;
obj.out();
return 0;
}
Output
Enter the first number : 56
Enter the second number : 234
The decremented elements for the objects are: 55 and 223
Explanation
This code showcases the overloading of the prefix decrement operator in C++. The OverLoad class represents two integer variables, a and b, and overloads the — operator to decrement both.
Upon execution, the program prompts the user to input two numbers, then decrements them using the overloaded — Operator and displays the decremented values. In the provided output, 56 and 234 are decremented to 55 and 223 respectively.
Example 3: Overloading a NOT (!) operator
#include <iostream>
using namespace std;
class NotOp {
private:
int a;
bool b;
public:
NotOp() : a(0), b(true) {}
void in() {
cout << "Enter the first number : ";
cin >> a;
cout<< "Enter true or false : ";
cin >> b;
}
// Overloading the NOT (!) operator
void operator ! () {
a= !a;
b= !b;
}
void out() {
cout<<"Output: "<<endl<< a<<endl<<b;
}
};
int main() {
NotOp obj;
!obj;
obj.out();
return 0;
}
Output
1
0
Explanation
This code demonstrates the overloading of the NOT (!) Operator in C++. The NotOp class includes an integer variable, a, and a boolean variable, b. It overloads the! The Operator will perform logical negation on both variables.
Upon execution, the program prompts the user to input a number and a boolean value, then applies the overloaded ! Operator and displays the negated values. In the provided output, the number is negated to 1 (if initially non-zero), and the boolean value is negated to 0.
Don’t miss out on Our free Basics of C++ course – the perfect starting point for aspiring programmers!
What are the rules for operator overloading in C++?
In C++, the rules of Operator overloading in c++ include:
- Overloaded operators must have at least one operand that is a user-defined type.
- Overloaded operators cannot change the precedence and associativity of operators.
- Certain operators cannot be overloaded. (dot), .* (pointer to member), :: (scope resolution), ?: (ternary conditional), and sizeof.
- The arity of the Operator cannot be changed; for instance, you cannot make + unary if it’s binary.
- Overloaded operators maintain their original meaning for built-in types.
- Some operators are not suitable for overloading. For example, &&, ||, ,, . (member selection), .* (member selection through a pointer), and:: (scope resolution).
- The overloaded operators can be member functions or global functions.
- Unary operators have one operand, binary operators have two, and ternary operators have three.
Which operators Cannot be overloaded?
- Conditional [?:], size of, scope(::), Member selector(.), member pointer selector(.*) and the casting operators.
- We can only overload the operators that exist and cannot create new operators or rename existing operators.
- At least one of the operands in overloaded operators must be user-defined, which means we cannot overload the minus operator to work with one integer and one double. However, you could overload the minus operator to work with an integer and a mystring.
- It is not possible to change the number of operands of an operator supports.
- All operators keep their default precedence and associations (what they use for), which cannot be changed.
- Only built-in operators can be overloaded.
Advantages of an operator overloading in C++
- Simplified Syntax: Operator overloading allows programmers to use notation closer to the target domain, making code more intuitive and expressive.
- Consistency: It provides similar support to built-in types for user-defined types, enhancing consistency and ease of use.
- Easier Understanding: Operator overloading can make programs more accessible to understand by allowing the use of familiar operators with user-defined types, which can improve code readability and maintainability.
Disadvantages of an operator overloading in C++
- Potential Misuse: With great power comes great responsibility. Overloading operators can lead to abuse or misuse, resulting in difficult-to-understand or maintain code.
- Complexity: Overuse or misuse of operator overloading can introduce complexity, especially when overloaded operators don’t behave as expected or when there’s ambiguity in their usage.
- Limited Overloading: While many C++ operations can be overloaded, there are some exceptions, such as the member access operators (. and ->) and the scope resolution operator (::). This limitation can sometimes restrict the flexibility of operator overloading.
What are Unary Operators and Binary Operator overloading?
Unary Operators Overloading
Unary operator overloading involves defining behaviors for operators that act on a single operand. For example, increment (++), decrement (—), logical NOT (!), and unary minus (–) are unary operators that can be overloaded in C++. This means you can redefine their behavior for your custom classes.
Example: Let us try overloading the increment and decrement operators through a C++ program.
#include<iostream>
using namespace std;
class UnaryOverload
{
int hr, min;
public:
void in()
{
cout<<"n Enter the time: n";
cin>>hr;
cout<<endl;
cin>>min;
}
void operator++(int) //Overload Unary Increment
{
hr++;
min++;
}
void operator--(int) //Overload Unary Decrement
{
hr--;
min--;
}
void out()
{
cout<<"nTime is "<<hr<<"hr "<<min<<"min";
}
};
int main()
{
UnaryOverload ob;
ob.in();
ob++;
cout<<"nn After Incrementing : ";
ob.out();
ob--;
ob--;
cout<<"nn After Decrementing : ";
ob.out();
return 0;
}
Output
Enter the time:
5
56
After Incrementing:
Time is 6hr 57 mins
After Decrementing:
Time is 4hr 55 min
Explanation
This code illustrates unary Operator overloading in C++. The UnaryOverload class represents time in hours and minutes. It overloads the unary increment (++) and decrement (–) operators to increment and decrement the time, respectively.
Upon execution, the program prompts the user to input the time, then increments it and displays the result. Subsequently, it decrements the time twice and shows the final result. In the provided output, the time is incremented from 5hr 56min to 6hr 57min and then decremented to 4hr 55min as expected.
Binary Operator Overloading
Binary Operator overloading defines behaviors for operators that act on two operands.
Common binary operators include addition (+), subtraction (-), multiplication (*), division (/), and comparison operators like equal to (==) and less than (<). By overloading these operators, you can specify how they should operate on objects of your custom classes, allowing for intuitive and natural expressions in your code.
Also, learn how the Binary Search Algorithm can complement your understanding of binary operator overloading.
Example: Let us see the following C++ code that elaborates the overloading of the addition operator.
#include <iostream>
using namespace std;
class Time {
private:
int hour;
int minute;
public:
Time() : hour(0), minute(0) {}
void in() {
cout << "Enter the time: ";
cin >> hour;
cin >> minute;
}
// Overload the + operator
Time operator + (const Time & obj) {
Time temp;
temp.hour = hour + obj.hour;
temp.minute = minute + obj.minute;
if (temp.minute>=60)
{
temp.hour+=1;
temp.minute-=60;
}
if (temp.hour>24)
temp.hour=1;
return temp;
}
void out() {
cout<<"Time is "<< hour<<"hrs "<<minute<<"min";
}
};
int main() {
Time T1, T2, result;
cout << "Enter first time in hours and minutes one by one :n";
T1.in();
cout << "Enter second time in hours and minutes one by one :n";
T2.in();
// T1 calls the operator function
// T2 is passed as an argument to the function
result = T1 + T2;
result.out();
return 0;
}
Output
Enter first time in hours and minutes one by one:
Enter the time:11
56
Enter second time in hours and minutes one by one:
Enter the time: 2
10
Time is 14hrs 6 min
Explanation
This code demonstrates binary Operator overloading in C++. The Time class represents time in hours and minutes. The + Operator is overloaded to add two Time objects together.
Upon execution, the program prompts the user to input two times, adds them using the overloaded + Operator, and displays the result. In the provided output, 11hrs 56min and 2hrs 10min are added together, resulting in 14hrs 6min.
Discover ‘C++ Projects To Work On In 2024‘ that will challenge and excite you as you hone your C++ proficiency.
Overloadable/Non-overloadable Operators
Now that you saw the overloading of unary and binary operators in C++ in the previous sections of this blog, you must know that not all operators can be overloaded. The operators that can be overloaded in C++ are known as overloadable operators. However, there are some non-overloadable operators as well that can’t be overloaded.
The list of non-overloadable operators goes as follows:
- Ternary operator (? 🙂
- Dot operator or member access operator (.)
- Pointer to member operator (.*)
- Scope resolution operator ( :: )
- Object type operator (typeid)
- Object size operator (sizeof)
These operators cannot be overloaded because doing so will cause significant programming problems. As an illustration, the sizeof operator returns the operand, which is the size of the object or datatype. The compiler evaluates this. It cannot be assessed in real-time. We can’t thus overburden it.
Overloading special operators in C++
Some of the special operators in C++ are as follows:
- new – It is used to allocate the memory dynamically.
- Delete – It is used to free the memory dynamically.
- [] – It is a subscript operator.
- -> – – It is a member access operators.
- = – It is used to assign the values.
- () – It is used for function call.
The operators other than listed above can be overloaded either as a member or as non-members. But in general, non-member overloading is recommended. Because:
- Symmetry: When a binary operator is defined as a class method, it must have objects as its operands. We should write like complex*5 but not like 5*complex because 5. operator*(complex)does not make any sense. In other words, a*b should be the same as b*a. Otherwise, it breaks the cumulativeness that the user is expecting from the *operator. So, in this case, we should use no-member operators overloading.
- Weak coupling: since a non-member method cannot access private member, it tends to make the class less coupled
Example:
Using unary operator:
//Overload ++ when used as prefix
#include<iostream.h>
Using namespace std;
Class count
{
Private:
Int value;
Public:
//constructor to initialize count to 5
Count() : value(5) {}
//overload ++ when used as prefix
Void operator ++ ()
{
++value;
}
Void display()
{
Cout<<”Count: “<<value<<endl;
}
};
Int main()
{
Count count1;
//call the “void operator ++ ()” function
++count1:
Count1.display();
Return 0;
}
Output
Count: 6
Explanation
In this code, when we write ++count1, the void operator++() function is triggered. This function increments the value attribute of the count1 object by 1. Operator overloading allows us to redefine how operators behave.
For instance, we could have made ++ increase the value by 100, but clarity is crucial in coding. Consistently and using overloaded operators ensures easy comprehension.
In this example, ++ is overloaded as a prefix. The syntax void operator++() is used, with int inside parentheses to indicate it’s a unary operator. This clarifies the usage, avoiding confusion.
Conclusion
Exploring Operator overloading in C++ has provided valuable insights into enhancing code readability and flexibility. By allowing custom definitions for operators, developers can streamline coding processes and improve code maintainability.
If you want to master C++ programming and its advanced concepts like operator overloading, consider enrolling in Great Learning’s free C++ course. Designed to equip learners with essential coding skills, this course lays a solid foundation for pursuing a career in software engineering.
Additionally, our Software Engineering Courses offer comprehensive training in software development methodologies, project management, and industry best practices, paving the way for a rewarding future in the tech industry.
Learning never stops, and neither should you! Unlock more learning opportunities with our free online courses designed to help learners enhance their knowledge for free.
FAQs
To overload an operator for a user-defined class in C++, you must define a member or non-member function with the appropriate operator syntax. For binary operators, such as + or -, you typically define a function that takes two operands, while unary operators, such as ++ or –, only require one operand. Additionally, some operators may need to be defined as friend functions to access private members of the class.
Operator overloading aligns with software engineering principles by promoting code reusability, readability, and maintainability. By overloading operators, developers can write concise and expressive code that closely mirrors the problem domain, leading to more natural and intuitive interfaces for user-defined types. This, in turn, contributes to the development of robust and scalable software systems.
No, operators cannot be overloaded for built-in types in C++. Operator overloading only applies to user-defined types, such as classes and structures. However, you can use function overloading to define different behaviors for functions that operate on built-in types.
Yes, you can overload the subscript Operator ([]) for non-array classes in C++. Overloading this Operator allows your class’s objects to be accessed using array-like syntax. For example, you can define custom behavior for accessing collection or container class elements.