C++ Operator Overloading With Programming Examples
Table of Contents
C++ Operator Overloading:
The feature in C++ programming that permits programmers to redefine the meaning of operator when they work on class objects is known as operator overloading.
Or
Defining a new position for the existing operator as for the class objects is called as operator overloading.
C++ Operator Overloading is one of the main features of object-oriented programming. The operators in C++ are actualized as functions. Hence, C++ Operator Overloading works fundamentally the same as function overloading. In function overloading, we discover that we can make various functions of the very name that work distinctively depending on parameter types. C++ Operator Overloading permits the programmer to change the conduct of the operator to perform various operations depending on the kind of operands.
We can redefine or overload the vast majority of the built-in operators accessible in C++. Accordingly we can utilize operators with user-defined types too.
Some of the important operators that can be overloaded in C++ are as follows:
- +, -, *, / and % Arithmetic operators
- (<<, >>) I/O operators
- ([]) Subscript operator
- (=) Assignment operator.
- Relational or comparison operators == and !=.
- Compound assignment operators +=, -=, *=, /=, %=.
- Parenthesis operator ( () ).
The operators that cannot be overloaded are as follows:
Following are the types of the Operators that cannot be overloaded.
- ?: (conditional)
- .(member selection)
- .*(member selection with pointer to member)
- :: (scope resolution)
- sizeof(object size information)
- typeid(object type information).
Amazon Purchase Links:
*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!
Rules and Restrictions on C++ Operator Overloading:
Following are some significant rules and limitations on C++ Operator Overloading:
- We can’t make another operator; just the existing operators can be overloaded.
- We can’t change the number of operands that an operator takes. For instance, overloaded unary operators remain unary operators and overloaded binary operators remain binary operators. Operators and, *, + and – all have both unary and binary versions. These unary and binary versions can be independently overloaded.
- We can’t change the working of an operator by C++ Operator Overloading. For instance, we can’t make the + operator as a take away operator.
- The related operators, as * and *= must be overloaded independently.
- The precedence of an operator can’t be changed by overloading. Notwithstanding, parentheses can be utilized to drive the request for assessment of overloaded operators in an expression.
- The cooperatively of an operator can’t be changed by overloading.
- The assignment operator (=) and address operator (&) don’t should be overloaded. Since these two operators are as of now overloaded in the C++ library. For instance: on the off chance that obj1 and obj2 are two objects of a similar class, at that point, we can utilize code obj1 = obj2; without overloading = operator. This code will copy the contents of obj2 to obj1. Also, we can utilize the address operator legitimately without overloading which will return the address of the object in memory.
Operator Function:
An operator is overloaded by declaring a special member function of the class known as operator function. This member function is defined inside the class using keyword ‘operator’ followed by the symbol of operator to be overloaded.
The general syntax to define operator function is as follows:
return-type operator sign (parameter list)
{
Body of function
}
Where
Return-type:
It indicates the type of value returned by the member function. If function returns anything, then keyword ‘void’ is used.
Operator:
It is a keyword of C++. It indicates the operator function.
Sign:
It is the sign or symbol of operator that is to be overloaded.
Parameter list:
It indicates the arguments that are passed to the function. When this operator function is called, the operations are performed on those arguments that are passed to the function.
Overloading the Arithmetic Operators:
Some of the most commonly used operators in C++ are the arithmetic operator +, -, *, and /. Please note that all of the arithmetic operators are binary operators. These operators are overloaded to increase their capabilities and enable them to work with user-defined objects in the same way as they work with the basic data types (such as int, long, and float, etc).
Example Write a program that adds and subtracts two integer values using binary C++ Operator Overloading:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#include <iostream> #include<conio.h> using namespace std; class temp { private: int data; public: void getvalue() { cin>>data; } temp operator+(temp ob) { temp t; t.data=data + ob.data; return t; } temp operator- (temp ob) { temp t; t.data = data - ob.data; return t; } int display() { return data; } }; int main() { temp obj1, obj2, sum, sub; cout<<"enter an integer value for obj1: "; obj1.getvalue(); cout<<"Enter an integer value for obj2: "; obj2.getvalue(); sum= obj1+obj2; sub=obj1-obj2; cout<<"Addition result is = "<<sum.display()<<endl; cout<<"Subtraction result is = "<<sub.display()<<endl; getch(); } |
In this program, the class temp has one data member ‘data’ of the integer data type. It additionally has four member function getvalue() to get data from the user, display() to display data, and two operator functions that are utilized to overload addition and subtraction operators.
In the main function, four objects of class temp are declared (made). The values are taken from users for both of the objects using getvalue() member function. At that point the data of the objects are added and subtracted using overloaded addition and subtraction operator individually. The result of addition is put away in object ‘sum’ and result of subtraction is store in object ‘sub’. These results of subtraction and addition are displayed on the computer screen using display() member function.
The values put away in objects obj1, obj2, sum, and sub of class temp are shown in the following figures:
The value of 20 and 10 are input in objects obj1 and obj2 respectively. After executing + overloaded operator, the value of data of object ‘sum’ (that is the object of temp class) becomes 20. Similarly, after the execution of – overloaded operator, the value of data of object ‘sub’ (that is also an object of temp class) is 10. The value of data of ‘sum’ and ‘sub’ are displayed using the display() function.
Example: write a program using class distance that creates an object and gets value from user in feet and inches. It then adds these values with the values of another object by overloading of + operator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#include <iostream> #include<conio.h> using namespace std; class string { private: char str[100]; public: void input() { cin>>str; } string operator+ (string s2) { string temp; strcpy(temp.str, str); strcat(temp.str, s2.str); return temp; } void print() { cout<<"combined String= "<<str<<endl; } }; int main() { string s1,s2,s3; cout<<"Enter string for 1st object:\n"; s1.input(); cout<<"Enter string for 2nd object:\n"; s2.input(); s3= s1+s2; s3.print(); getch(); } OutPut: Enter string for 1st object: Programm Enter string for 2nd object: ing Combined string = programming |
In this program, the class string has a data member ‘str’ of string type. The member function input() takes a string from the user and function ‘print()’ displays on the screen. The + operator function concatenates the strings of both the objects.
In the main() function, two objects of class string type are created. The strings in data member ‘str’ of ‘s1’ and ‘s2’ are entered. These strings are concatenated (combined) using statement s3= s1+s2. The + operator function concatenates the string s1 and s2, and stores the concatenated string in s3.
Overloading I/O operators:
I/O operator are stream extraction operator >> and the stream insertion operator <<, C++ is able to input and output the built-in data types using these operators. The stream insertion and stream extraction operators also can be overloaded to perform input and output for user-defined types like and object.
Overloading operator << and overloading operator >> are similar to overloading operator +. These are binary operators. But in overloading operator <<, the left operand is the ‘cout’ object and the right operand is the class object. The ‘cout’ is actually an object of type ostream. Similarly, in overloading operator >>, the left operand is the cin object and the right operand is the class object cin which is an object of type istream.
The general syntax for overloading I/O operator is as follows:
Return-type operator sign (parameter list)
{
Body of function
}
Where
Return-type:
It indicates the return type of overloaded I/O operator. The return type for overloaded stream extraction operator is ostream& and for overloaded stream insertion operator is istream&.
Operator:
It is a keyword of C++. It indicates the operator function.
Sign:
It indicates the sign of overloaded I/O operator. The sign for overloaded stream extraction operator is << and overloaded stream insertion operator is >>.
Parameter list:
There are two parameters for overloaded I/O operators. The first is of ostream type for stream extraction overloading and istream type for stream insertion overloading, and the second is of that class whose object is used.
How to displaying class data using stream extraction overloading operator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <iostream> using namespace std; class student { private: int roll_no; float marks; public: student(int r, float m) { roll_no=r; marks=m; } friend ostream& operator<<(ostream &out, student &st) { out<<"roll_no: "<<st.roll_no<<endl; out<<"marks: "<<st.marks<<endl; return out; } }; int main() { student s1(1,490), s2(2, 600); cout<<"Record of Studen1 is:\n"; cout<<s1; cout<<"Record of Studen2 is:\n"; cout<<s2; } |
In this program, each object of student contains the roll no and marks. In the main() function, the statement “cout<<s1;” invokes(calls) the overloaded stream extraction operator that displays the record of student or roll number 1. Similarly, the statement “cout<<s2;” displays the record of student or roll number 2. It displays the chain of roll no and marks by only using a single statement in the main function.
Example write program which take record of two employees using overloaded stream insertion operator, and display them on screen using stream extraction overloading operator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <iostream> using namespace std; class employee { private: int emp_no; char name[10], address[40]; public: friend istream& operator>>(istream &in, employee &emp) { cout<<"Enter employee no: "; in>>emp.emp_no; cout<<"Enter employee Name: "; in>>emp.name; cout<<"Enter employee address: "; in>>emp.address; return in; } friend ostream& operator<<(ostream &out, employee &emp) { out<<"Emp no: "<<emp.emp_no<<endl<<"Name: "<<emp.name<<endl<<"Address: "<<emp.address<<endl; return out; } }; int main() { employee e1,e2; cout<<"enter record for employee 1:\n"; cin>>e1; cout<<"enter record for employee 2:\n"; cin>>e2; cout<<"record of employee 1:\n"; cout<<e1; cout<<"record of employee 2:\n"; cout<<e2; } |
In this program, two I/O operator overloaded functions in the ‘employee’ class are defined. C++ Operator Overloading function of stream insertion operator ( >> ) is defined to input data for data member of class ‘employee’. The C++ Operator Overloading function of stream extraction operator (<<) is defined to show the record of the employee.
In the main() function, two objects of the class employee are declared. The statement cin<<e1; invokes the overloaded stream insertion operator that takes input for the first employee’s record from the user and the statement cin>>e2; takes input for the second record. The records of both the employees are displayed using overloaded stream extraction.
Overloading Comparison Operators:
There are different relational operators upheld by C++ language like(<, >, <=, >=, ==, and so on) which can be utilized to compare C++ built-in data types. Comparison operators are binary operators. As you already know a comparison operator is used to compare two operands, the result of the comparison is returned in the form of true or false. These operators can be overloaded which can be utilized to compare the objects of a class.
Example: write a program that compares distances using overloaded comparison operator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#include <iostream> using namespace std; class distance { private: int feet; int inches; public: distance(int f, int i) { feet = f; inches=i; } void display() { cout<<"Feet: "<<feet<<endl<<"inches:"<<inches<<endl; } int operator< (const distance& d) { if((feet==d.feet) && (inches < d.inches)) return 1; else return 0; } }; int main() { distance d1(11, 10), d2(5, 11); cout<<"Values of d1"<<endl; d1.display(); cout<<"Values of d2"<<endl; d2.display(); if(d1<d2) cout<<endl<<"d1 is less than d2"<<endl; else cout<<endl<<"d2 is less than d1"<<endl; } Output: Value of d1 Feet:11 Inches:10 Value of d2 Feet:5 Inches:11 d2 is less than d1 |
in this program, the class ‘distance’ contains two data members, feet and inches. It also contains a C++ Operator Overloading function which compares two distances and returns 1 if both of the values of data members of object 1 is less than the value of data member of object 2, otherwise 0.
In the main() function, two objects of class distance are declared. The statement d1<d2 calls the C++ Operator Overloading function and returns the value on the basis of the values of their data members.
Example write a program that compares the length of two string that either they are equal or not using overloaded comparison operator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include <iostream> #include<conio.h> #include<string.h> using namespace std; class mystring { private: char str[50]; int len; public: mystring (char s[]) { strcpy(str, s); len=strlen(str); } int operator == (mystring s) { if(len==s.len) return 1; else return 0; } }; int main() { mystring s1("Electronic"), s2("clinic"); if(s1==s2) cout<<"both string have same length"; else cout<<"both string have different lengths"; } |
In this program, the class ‘mystring’ has two data members: str of string type and len of int type. The == operator overloading function compares the length of the string if they are equal then it returns 1 otherwise it returns 0.
In the main() function, two objects of class ‘mystring’ are declared. The statement “if( s1==s2 ) calls (invokes) the C++ Operator Overloading function and return value on the basis of the values of their data members. Because the length of these string is different, so value 1 (true value) will be returned.
Overloading Unary Operators:
The unary operators operate on a single operand. Following are some examples of unary operators:
- The increment (++) and decrement (–) operators.
- The unary plus (+) operator.
- The unary minus(-) operator.
- The logical not (!) operator.
All these operands are implemented in an identical manner. The unary operator operates on the object for which it was called. Normally, this operator appears on the left side of the object such as !obj, -obj, and ++obj but sometime it can be used as postfix as well such as obj++ or obj–
Example: write a program to explain prefix and postfix increment operator using operator function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include <iostream> #include<conio.h> #include<string.h> using namespace std; class incre { private: int data; public: incre() { data=0; } void operator++() { ++data; } void operator++(int) { data++; } void display() { cout<<"data ="<<data<<endl; } }; int main() { incre obj; cout<<"Before increment operation the value of obj:"; obj.display(); ++obj; cout<<"After prefix increment operation the value of obj:"; obj.display(); obj++; cout<<"After postfix increment operation the value of obj:"; obj.display(); obj++; } |
In this program, the class incre has a data member ‘data’ which is set to zero in the default constructor. There are two operator functions: one for prefix increment and the second for postfix increment the int inside the bracket of the postfix increment operator function is used to give information to the compiler that it is the postfix version of the operator. It does not indicate the integer.
In the main() function, an object ‘obj’ is declared of class ‘incre’ type. The statement “++obj ” call (invokes) the operator function “void operator ++()”, and display() function of the object displays the result on the screen. The statement “obj++” invokes the operator function “void operator ++(int) ” and the display() function of the object displays result on the screen.
Example: write a program to explain prefix and postfix decrement operator using operator function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include <iostream> #include<conio.h> #include<string.h> using namespace std; class decre { private: int data; public: decre () { data = 0; } decre operator-- () { decre temp; temp.data = ++data; return temp; } decre operator-- (int) { decre temp; temp.data = data++; return temp; } void display () { cout << "Data = " << data << endl; } }; int main () { decre obj, obj1; cout << "Before decrement operation the value of obj:"; obj.display (); cout << "Before decrement operation the value of obj1:"; obj1.display (); obj1 = --obj; cout << "After postfix decrement operation the value of obj:"; obj.display (); cout << "After postfix decrement operation the value of obj"; obj1.display(); obj--; cout<<"After Postfix decrement operation the value of obj:"; obj.display(); cout<<"After Postfix decrement operation the value of obj1:"; obj1.display(); } |
In the above program, the class ‘decre’ has a data member ‘data’ which is set to zero in the default constructor. This class has two operator functions one for prefix increment and the second for postfix decrement. The function in which int is inside the bracket is the postfix decrement operator function and the other operator function in prefix decrement operator function.
In the main() function, two objects obj and obj1 are declared of class ‘decre’ type. The statement ‘obj1 = –obj” invokes the C++ Operator Overloading function ‘decre operator –()’ stores the result in obj1, and then displays on the screen. While the statement ‘obj1 = obj– ‘ invokes the C++ Operator Overloading function ‘decre operator –(int)’ stores the result in obj1, and then displays on the screen.
Overloading Subscript Operator:
The subscript operator is normally used to access array elements. This operator can be overloaded to enhance the existing functionality of C++ arrays.
The subscript operator is typically overloaded to provide direct access to the private one-dimensional array that is the data member of the class. The single parameter is passed using subscript operator [].
In the C++ Operator Overloading function of subscript operator, the operator []is returning a reference because operator [] has higher precedence even than the assignment operator, that’s why the function should return the actual array element so that other operation could perform on the actual array element.
One of the advantages of overloading the subscript operator is that we can make it safer than accessing arrays directly. Normally, when accessing arrays, the subscript operator does not check whether the index is valid or not.
Example write a program to explain the overloading of subscript operator []:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <iostream> #include<conio.h> #include<string.h> using namespace std; const int SIZE = 10; class saferarray { private: int arr[SIZE]; public: saferarray() { for(int i=0; i<SIZE; i++) { arr[i]=i; } } int &operator[] (int i) { if(i>SIZE) { cout<<"index out of bound"<<endl; return arr[0]; } return arr[i]; } }; int main () { saferarray a; cout<<"Value of A[2] : "<<a[2]<<endl; cout<<"Value of A[5] : "<<a[5]<<endl; cout<<"Value of A[12] : "<<a[12]<<endl; } |
In the above program, the class ‘saferarry’ has an array that is initialized the values equal to their index number in the default constructor. The class has a subscript operator function that returns the value of the index of an array that is given as a parameter to the function. It also shows a message on an invalid index number.
In the main() function, an object a of class ‘saferarray’ type is declared. Three output statements are also given to show the values of different elements of the array. The first statement displays the value of the third element of the array, while the second statement displays a message ‘index out of bound’ because the index is outbound and displays the value of a[12] as 0.
Overloading Parenthesis Operator:
All of the overloaded operators that we have discuses earlier, take either one parameter or two parameters. Their number of parameters is fixed. But the overloaded parenthesis operator () does not fix any number of parameters. It allows taking any number of parameters (one, two, multiple, or no parameter).
Overloaded subscript operator [] provides direct access to the private one-dimensional array, but an overloaded parenthesis operator () provides access to the private two-dimensional array as it supports the passing of two indexes as parameters.
Example write a program to explain the overloading of parenthesis operator () using parenthesis operator function having two parameters and no parameter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include <iostream> #include<conio.h> #include<string.h> using namespace std; class matrix { private: double data[4][4]; public: matrix() { for(int col=0; col<4; col++) for(int row=0; row<4; row++) data[row][col]=0.0; } double& operator() (int c, const int r) { if((c>=0)&&(c<4)) if((r>=0)&& (r<4)) return data[r][c]; } void operator()() { for(int col=0; col<4; col++) for(int row =0; row<4; row++) data[row][col]=0.0; } }; int main () { matrix m; m(1,2)=4.5; cout<<"Value at M[1][2] is: "<<m(1,2)<<endl; m(); cout<<"Value at M[1][2] is: "<<m(1,2)<<endl; } |
In the above program, the class matrix has a data member of two-dimensional array data[4][4]. The class has a default constructor that sets all the values of all the indexes of the two-dimensional array to zero. This class has two C++ Operator Overloading functions for parenthesis operator, one of them take two parameters, row and column and returns the value to that index form the 2-D array, and the second C++ Operator Overloading function has no parameter, it sets the array to zero, working the same way as default constructor.
In the main() function, an object m is declared of class ‘matrix’ type. It sets the value 4.5 to data[1][2] using two parameters parenthesis operator function, and displays in on the screen. Then it erases the array using operator function with no parameter, and displays the same index on the screen.