Sunteți pe pagina 1din 25

Operator Overloading in C++ 

C++ provides a special function to change the current functionality of some operators within its 
class which is often called as operator overloading. Operator Overloading is the method by 
which we can change the function of some specific operators to do some different task. 
 
In C++, we can make operators to work for user defined classes. This means C++ has the 

ability to provide the operators with a special meaning for a data type, this ability is known as 

operator overloading. 

For example, we can overload an operator ‘+’ in a class like String so that we can concatenate 

two strings by just using +. 

Other example classes where arithmetic operators may be overloaded are Complex Number, 

Fractional Number, Big Integer, etc. 

This can be done by declaring the function, its syntax is, 

Return_Type classname :: operator op(Argument list)

Function Body

In the above syntax ​Return_Type​ is value type to be returned to another object, o​ perator op​ is 

the function where the o​ perator​ is a keyword and ​op​ is the operator to be overloaded. 

Operator function must be either non-static (member function) or friend function. 

Operator Overloading can be done by using ​three approaches​, they are 

1. Overloading unary operator. 


2. Overloading binary operator. 
3. Overloading binary operator using a friend function. 
 

 
Below are some criteria/rules to define the operator function: 

● In case of a non-static function, the binary operator should have only one 
argument and unary should not have an argument. 
● In the case of a friend function, the binary operator should have only two 
argument and unary should have only one argument. 
● All the class member object should be public if operator overloading is 
implemented. 
● Operators that cannot be overloaded are ​.​ ​.*​ ​::​ ?​ : 
● Operator cannot be used to overload when declaring that function as friend 
function =
​ ​ ​()​ ​[]​ -​ >​. 

Rules of Operator Overloading 

1. Overloading Unary Operator​: Let us consider to overload (-) unary operator. In 
unary operator function, no arguments should be passed. It works only with one 
class objects. It is a overloading of an operator operating on a single operand. 
Example: 
Assume that class Distance takes two member object i.e. feet and inches, create 
a function by which Distance object should decrement the value of feet and 
inches by 1 (having single operand of Distance Type). 

// C++ program to show unary operator overloading  

#include <iostream.h>  
class Distance {  
public:  
int feet, inch; // Member Object  
Distance(int f, int i)  // Constructor to initialize the object's value  
{  
this->feet = f;  
this->inch = i;  
}  
 
// Overloading(-) operator to perform decrement operation of Distance object  
void operator-()  
{  
feet--;  
inch--;  
cout << "\nFeet & Inches(Decrement): " << feet << "'" << inch;  
}  
};  
int main()  
{  
Distance d1(8, 9);  // Declare and Initialize the constructor  
-d1;  // Use (-) unary operator by single operand  
return 0;  
}  
Output: 
 
Feet & Inches(Decrement): 7'8
1. In the above program, it shows that no argument is passed and no return_type 
value is returned, because unary operator works on a single operand. (-) operator 
change the functionality to its member function. 
 
Note:​ ​d2 = -d1​ will not work, because operator-() does not return any value. 
 
2. Overloading Binary Operator​: In binary operator overloading function, there should 
be one argument to be passed. It is overloading of an operator operating on two 
operands. 
Let’s take the same example of class Distance, but this time, add two distance 
objects. 
 
 
 
 
// C++ program to show binary operator overloading  

#include <iostream.>  

class Distance {  

public:  

int feet, inch;  // Member Object  

Distance()  // No Parameter Constructor  

{  

this->feet = 0;  

this->inch = 0;  

}  

// Constructor to initialize the object's value Parametrized Constructor  

Distance(int f, int i)  

{  

this->feet = f;  

this->inch = i;  

}  

// Overloading (+) operator to perform addition of two distance object  

Distance operator+(Distance& d2)  // Call by reference  

{  

Distance d3;  // Create an object to return  

d3.feet = this->feet + d2.feet; // Perform addition of feet and inches  

d3.inch = this->inch + d2.inch;  

return d3; // Return the resulting object  

}  

};  
 

int main()  
{  
Distance d1(8, 9);// Declaring and Initializing first object  
 
 
Distance d2(10, 2); // Declaring and Initializing second object  
 
 
Distance d3; // Declaring third object  
 
 
d3 = d1 + d2; // Use overloaded operator  
 
 
// Display the result  
cout << "\nTotal Feet & Inches: " << d3.feet << "'" << d3.inch;  
return 0;  
}  
 
Output: 
Total Feet & Inches: 18'11
1.
Here in the above program, 
See Line no. 26​, D​ istance operator+(Distance &d2)​, here return type of function is 
distance and it uses call by references to pass an argument. 
See Line no. 49​, d​ 3 = d1 + d2;​ here, d1 calls the operator function of its class 
object and takes d2 as a parameter, by which operator function return object and 
the result will reflect in the d3 object. 
Pictorial View of working of Binary Operator: 

 
2. Overloading Binary Operator using a Friend function​: In this approach, the 
operator overloading function must precede with friend keyword, and declare a 
function class scope. Keeping in mind, friend operator function takes two 
parameters in a binary operator, varies one parameter in a unary operator. All the 
working and implementation would same as binary operator function except this 
function will be implemented outside of the class scope. 
Let’s take the same example using the friend function. 

// C++ program to show binary operator overloading  

#include <iostream>  

class Distance {  

public:  
 

// Member Object  

int feet, inch;  

// No Parameter Constructor  

Distance()  

{  

this->feet = 0;  

this->inch = 0;  

}  

// Constructor to initialize the object's value Parametrized Constructor  

Distance(int f, int i)  

{  

this->feet = f;  

this->inch = i;  

}  

// Declaring friend function using friend keyword  

friend Distance operator+(Distance&, Distance&);  

};  

// Implementing friend function with two parameters  

Distance operator+(Distance& d1, Distance& d2) // Call by reference  

{  

// Create an object to return  

Distance d3;  

// Perform addition of feet and inches  

d3.feet = d1.feet + d2.feet;  

d3.inch = d1.inch + d2.inch;  

return d3;  // Return the resulting object  

}  
int main()  
{  
Distance d1(8, 9); // Declaring and Initializing first object  
 
Distance d2(10, 2); // Declaring and Initializing second object  
 
Distance d3; // Declaring third object  
 
d3 = d1 + d2; // Use overloaded operator  
 
// Display the result  
cout << "\nTotal Feet & Inches: " << d3.feet << "'" << d3.inch;  
return 0;  
}  
 
Output: 
Total Feet & Inches: 18'11
Here in the above program, operator function is implemented outside of class scope by 
declaring that function as the friend function. 

In these ways, an operator can be overloaded to perform certain tasks by changing the 
functionality of operators. 

A simple and complete example 

#include<iostream>  
using namespace std;  
 
class Complex  
{  
private:  
int real, imag;  
public:  
Complex(int r = 0, int i =0)  //{real = r; imag = i;}  
 
// This is automatically called when '+' is used with between two Complex objects  
 
Complex operator + (Complex const &obj)  
{  
Complex res;  
res.real = real + obj.real;  
res.imag = imag + obj.imag;  
return res;  
}  
void print() { cout << real << " + i" << imag << endl; }  
};  
 
int main()  
{  
Complex c1(10, 5), c2(2, 4);  
Complex c3 = c1 + c2; // An example call to "operator+"  
c3.print();  
}  
Output: 

12 + i9
 

What is the difference between operator functions and normal functions? 

Operator functions are same as normal functions. The only differences are, name of an 

operator function is always operator keyword followed by symbol of operator and operator 

functions are called when the corresponding operator is used. 

Following is an example of global operator function. 

#include<iostream.h>  

class Complex 
{  
private:  
int real, imag;  
public:  
Complex(int r = 0, int i =0) //{real = r; imag = i;}  
void print()  
{  
cout << real << " + i" << imag << endl;  
}  
 
// The global operator function is made friend of this class so that it can access private 
members  
friend Complex operator + (Complex const &, Complex const &);  
};  
 
Complex operator + (Complex const &c1, Complex const &c2)  
{  
return Complex(c1.real + c2.real, c1.imag + c2.imag);  
}  
 
int main()  
{  
Complex c1(10, 5), c2(2, 4);  
Complex c3 = c1 + c2;  // An example call to "operator+"  
c3.print();  
return 0;  
}  
 
 
Can we overload all operators? 

Almost all operators can be overloaded except few. Following is the list of operators that 

cannot be overloaded. 

. (dot)

::

?:

sizeof

Why can’t . (dot), ::, ?: and sizeof be overloaded? 

See t​ his ​for answers from Stroustrup himself. 

Important points about operator overloading 

1)​ For operator overloading to work, at least one of the operands must be a user defined class 

object. 

2)​ A
​ ssignment Operator:​ Compiler automatically creates a default assignment operator with 

every class. The default assignment operator does assign all members of right side to the left 

side and works fine most of the cases (this behavior is same as copy constructor). See ​this 

for more details. 

3)​ C
​ onversion Operator:​ We can also write conversion operators that can be used to convert 

one type to another type. 

#include <iostream.h>  

class Fraction  

{  
int num, den;  

public:  

Fraction(int n, int d) { num = n; den = d; }  

// conversion operator: return float value of fraction  

operator float() const {  

return float(num) / float(den);  

}  

};  

int main() {  

Fraction f(2, 5);  

float val = f;  

cout << val;  

return 0;  

}  

Output: 

0.4
Overloaded conversion operators must be a member method. Other operators can either be 

member method or global method. 

4) ​Any constructor that can be called with a single argument works as a conversion 

constructor, means it can also be used for implicit conversion to the class being constructed. 

#include<iostream>  

class Point {  

private:  

int x, y;  

public:  

Point(int i = 0, int j = 0) {  

x = i; y = j;  

}  
void print() {  

cout << endl << " x = " << x << ", y = " << y;  

}  

};  

int main() {  

Point t(20, 20);  

t.print();  

t = 30; // Member x of t becomes 30  

t.print();  

return 0;  

Output: 

x = 20, y = 20

x = 30, y = 0
We will soon be discussing overloading of some important operators like new, delete, comma, 

function call, arrow, etc. 

Rules for operator overloading 


In C++, following are the general rules for operator overloading. 

1) Only built-in operators can be overloaded. New operators can not be created. 

2) Arity of the operators cannot be changed. 

3) Precedence and associativity of the operators cannot be changed. 

4) Overloaded operators cannot have default arguments except the function call operator () 

which can have default arguments. 


5) Operators cannot be overloaded for built in types only. At least one operand must be used 

defined type. 

6) Assignment (=), subscript ([]), function call (“()”), and member selection (->) operators must 

be defined as member functions 

7) Except the operators specified in point 6, all other operators can be either member 

functions or a non member functions. 

8 ) Some operators like (assignment)=, (address)& and comma (,) are by default overloaded. 

Overloading New and Delete operator in c++


The new and delete operators can also be overloaded like other operators in C++. New and 

Delete operators can be overloaded globally or they can be overloaded for specific classes. 

● If these operators are overloaded using member function for a class, it means 
that these operators are overloaded o
​ nly for that specific class​. 
● If overloading is done outside a class (i.e. it is not a member function of a class), 
the overloaded ‘new’ and ‘delete’ will be called anytime you make use of these 
operators (within classes or outside classes). This is ​global overloading​. 

Syntax for overloading the new operator : 

void* operator new(size_t size); 


 

The overloaded new operator receives size of type size_t, which specifies the number of bytes 

of memory to be allocated. The return type of the overloaded new must be void*.The 

overloaded function returns a pointer to the beginning of the block of memory allocated. 

 
 
Syntax for overloading the delete operator : 

void operator delete(void*); 


 

The function receives a parameter of type void* which has to be deleted. Function should not 

return anything. 

NOTE:​ Both overloaded new and delete operator functions are ​static members b
​ y default. 

Therefore, they don’t have access to ​this pointer .​  

Overloading new and delete operator for a specific class 

// CPP program to demonstrate Overloading new and delete operator for a specific class  
#include<iostream>  
#include<stdlib.h>  
using namespace std;  
class student  
{  
string name;  
int age;  
public:  
student()  
{  
cout<< "Constructor is called\n" ;  
}  
student(string name, int age)  
{  
this->name = name;  
this->age = age;  
}  
void display()  
{  
cout<< "Name:" << name << endl;  
cout<< "Age:" << age << endl;  
}  
void * operator new(size_t size)  
{  
cout<< "Overloading new operator with size: " << size << endl;  
void * p = ::new student();  
//void * p = malloc(size); will also work fine  
 
return p;  
}  
 
void operator delete(void * p)  
{  
cout<< "Overloading delete operator " << endl;  
free(p);  
}  
};  
 
int main()  
{  
student * p = new student("Yash", 24);  
 
p->display();  
delete p;  
}  
 
Overloading new operator with size: 16
Constructor is called
Name:Yash
Age:24
Overloading delete operator
NOTE: ​In the above new overloaded function, we have allocated dynamic memory through 

new operator, but it should be global new operator otherwise it will go in recursion 

void *p = new student(); // this will go in recursion asnew will be overloaded again and again 

void *p = ::new student(); // this is correct 

Global overloading of new and delete operator 

// CPP program to demonstrate Global overloading of new and delete operator  

#include<iostream>  

#include<stdlib.h>  

using namespace std;  

void * operator new(size_t size)  

{  

cout << "New operator overloading " << endl;  

void * p = malloc(size);  

return p;  

}  

void operator delete(void * p)  

{  

cout << "Delete operator overloading " << endl;  

free(p);  

}  

int main()  

{  

int n = 5, i;  

int * p = new int[3];  


 

for (i = 0; i<n; i++)  

p[i]= i;  

cout << "Array: ";  

for(i = 0; i<n; i++)  

cout << p[i] << " ";  

cout << endl;  

delete p;  

}  

Output : 

New operator overloading

Array: 0 1 2 3 4

Delete operator overloading

NOTE: ​In the code above, in new overloaded function we cannot allocate memory using ::new 

int[5] as it will go in recursion. We need to allocate memory using malloc only. 

Why to overload new and delete? 

1. The overloaded new operator function can accept arguments; therefore, a class 
can have multiple overloaded new operator functions. This gives the programmer 
more flexibility in customizing memory allocation for objects. For example: 
void *operator new(size_t size, char c)  
{  
void *ptr;  
ptr = malloc(size);  
if (ptr!=NULL)  
*ptr = c;  
return ptr;  
}  
main()  
{  
char *ch = new('#') char;  
}  
NOTE:  
1. Code will not only allocate memory for single character but will also initialize the 
allocated memory with # character. 
2. Overloaded new or delete operators also provide Garbage Collection for class’s 
object. 
3. Exception handling routine can be added in overloaded new operator function. 
4. Sometimes you want operators new and delete to do something customized that 
the compiler-provided versions don’t offer. For example, You might write a custom 
operator delete that overwrites deallocated memory with zeros in order to 
increase the security of application data. 
5. We can use realloc() function in new function to re-allocate memory dynamically. 
6. Overloaded new operator also enables programmers to squeeze some extra 
performance out of their programs. For example, In a class, to speed up the 
allocation of new nodes, a list of deleted nodes is maintained so that their 
memory can be reused when new nodes are allocated.In this case, the overloaded 
delete operator will add nodes to the list of deleted nodes and the overloaded new 
operator will allocate memory from this list rather than from the heap to speedup 
memory allocation. Memory from the heap can be used when the list of deleted 
nodes is empty. 

Program  to  concatenate  two  strings  using  Operator 


Overloading 
Given two strings. The task is to concatenate the two strings using Operator Overloading in 

C++. 

Example:

Input: str1 = "hello", str2 = "world"


Output: helloworld

Input: str1 = "Ocean", str2 = "World"


Output: OceanWorld

Approach 1​: Using unary operator overloading. 

● To concatenate two strings using unary operator overloading. Declare a class with 
two string variables. 
● Create an instance of the class and call the Parametrized constructor of the class 
to initialize those two string variables with the input strings from the main 
function. 

● Overload the unary operator to concatenate these two string variables for an 
instance of the class. 
● Finally, call the operator function and concatenate two class variables. 

Below is the implementation of the above approach: 

// C++ Program to concatenate two string using unary operator overloading


#include <iostream>
#include <string.h>
 
// Class to implement operator overloading function for concatenating the strings  
class AddString {  
 
public:  
// Classes object of string  
char s1[25], s2[25];  
 
// Parametrized Constructor  
AddString(char str1[], char str2[])  
{  
// Initialize the string to class object  
strcpy(this->s1, str1);  
strcpy(this->s2, str2);  
}  
 
// Overload Operator+ to concat the string  
void operator+()  
{  
cout << "\nConcatenation: " << strcat(s1, s2);  
}  
};  
 
// Driver Code  
int main()  
{  
// Declaring two strings  
char str1[] = "Great";  
char str2[] = "People";  
 
// Declaring and initializing the class  
// with above two strings  
AddString a1(str1, str2);  
 
// Call operator function  
+a1;  
return 0;  
}  
 
Output: 
Concatenation: ​GreatPeople 
 

Approach 2:​ Using binary operator overloading. 

● Declare a class with a string variable and an operator function ‘+’ that accepts an 
instance of the class and concatenates it’s variable with the string variable of the 
current instance. 
● Create two instances of the class and initialize their class variables with the two 
input strings respectively. 
● Now, use the overloaded operator(+) function to concatenate the class variable of 
the two instances. 

Below is the implementation of the above approach: 

// C++ Program to concatenate two strings using binary operator overloading


#include <iostream>  
#include <string.h>  
 
// Class to implement operator overloading function for concatenating the strings  
class AddString {  
 
public:  
// Class object of string  
char str[100];  
 
// No Parameter Constructor  
AddString() {}  
 
// Parametrized constructor to  
// initialize class Variable  
AddString(char str[])  
{  
strcpy(this->str, str);  
}  
 
// Overload Operator+ to concatenate the strings  
AddString operator+(AddString& S2)  
{  
// Object to return the copy  
// of concatenation  
AddString S3;  
 
// Use strcat() to concat two specified string  
strcat(this->str, S2.str);  
 
// Copy the string to string to be return  
strcpy(S3.str, this->str);  
 
// return the object  
return S3;  
}  
};  
int main()  
{  
// Declaring two strings  
char str1[] = "Get";  
char str2[] = "ForWorld";  
 
// Declaring and initializing the class with above two strings  
AddString a1(str1);  
AddString a2(str2);  
AddString a3;  
 
// Call the operator function  
a3 = a1 + a2;  
cout << "Concatenation: " << a3.str;  
 
return 0;  
}  
 
Output: 
Concatenation: ​Get​ForWorld 

 
Program to compare two Strings using Operator Overloading 
Given two strings, how to check if the two strings are equal or not, using Operator 

Overloading. 

Examples:

Input:​ ABCD, XYZ


Output:​ ABCD is not equal to XYZ
ABCD is greater than XYZ

Input:​ Great, Great


Output:​ Great is equal to Great

Approach:​ Using binary operator overloading. 

● Declare a class with a string variable and operator function ‘==’, ‘<=' and '>=’ that 
accepts an instance of the class and compares it’s variable with the string 
variable of the current instance. 
● Create two instances of the class and initialize their class variables with the two 
input strings respectively. 
● Now, use the overloaded operator(==, <= and >=) function to compare the class 
variable of the two instances. 

 
Below is the implementation of the above approach: 

// C++ program to compare two Strings using Operator Overloading

#include <cstring>  
#include <iostream>  
#include <string.h>  
 
// Class to implement operator overloading function for concatenating the strings  
class CompareString {  
 
public:  
// Classes object of string  
char str[25];  
// Parametrized Constructor  
CompareString(char str1[])  
{  
// Initialize the string to class object  
strcpy(this->str, str1);  
}  
// Overloading '==' under a function which returns integer 1/true if left operand string  
// and right operand string are equal. (else return 0/false)  
int operator==(CompareString s2)  
{  
if (strcmp(str, s2.str) == 0)  
return 1;  
else 
return 0;  
}  
 
// Overloading '<=' under a function which returns integer 1/true  
// if left operand string is smaller than or equal to the right operand string.  
// (else return 0/false)  
int operator<=(CompareString s3)  
{  
if (strlen(str) <= strlen(s3.str))  
return 1;  
else 
return 0;  
}  
// Overloading '>=' under a function which returns integer 1/true  
// if left operand string is larger than or equal to the right operand string.  
//(else return 0/false)  
 
int operator>=(CompareString s3)  
{  
if (strlen(str) >= strlen(s3.str))  
return 1;  
else 
return 0;  
}  
};  
 
void compare(CompareString s1, CompareString s2)  
{  
 
if (s1 == s2)  
cout << s1.str << " is equal to " 
<< s2.str << endl;  
else {  
cout << s1.str << " is not equal to " 
<< s2.str << endl;  
if (s1 >= s2)  
cout << s1.str << " is greater than " 
<< s2.str << endl;  
else 
cout << s2.str << " is greater than " 
<< s1.str << endl;  
}  
}  
 
void testcase1()  // Testcase1 
{  
// Declaring two strings  
char str1[] = "Geeks";  
char str2[] = "ForGeeks";  
 
// Declaring and initializing the class with above two strings  
CompareString s1(str1);  
CompareString s2(str2);  
cout << "Comparing \"" << s1.str << "\" and \""<< s2.str << "\"" << endl;  
compare(s1, s2);  
}  
 
 
 
 
 
 
void testcase2() // Testcase2  
{  
// Declaring two strings  
char str1[] = "Geeks";  
char str2[] = "Geeks";  
 
// Declaring and initializing the class with above two strings  
CompareString s1(str1);  
CompareString s2(str2);  
 
cout << "\n\nComparing \"" << s1.str << "\" and \""<< s2.str << "\"" << endl;  
 
compare(s1, s2);  
}  
 
int main()  
{  
testcase1();  
testcase2();  
 
return 0;  
}  
 
Output: 
Comparing "Geeks" and "ForGeeks"
Geeks is not equal to ForGeeks
ForGeeks is greater than Geeks

Comparing "Geeks" and "Geeks"


Geeks is equal to Geeks

S-ar putea să vă placă și