0% found this document useful (0 votes)
88 views

Operator Overloading

1. Operator overloading allows defining special behaviors for operators (like +, -, etc.) when used with user-defined types. This is done by creating operator functions. 2. Operator functions can be member functions or non-member (friend) functions. Member functions take the class object as the implicit first parameter, while friend functions require all parameters to be explicit. 3. Common operators that are overloaded include +, -, *, /, ++, --, =, etc. This allows user-defined types to be used with operators in the same way as built-in types.

Uploaded by

Dhanraj Kumar
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)
88 views

Operator Overloading

1. Operator overloading allows defining special behaviors for operators (like +, -, etc.) when used with user-defined types. This is done by creating operator functions. 2. Operator functions can be member functions or non-member (friend) functions. Member functions take the class object as the implicit first parameter, while friend functions require all parameters to be explicit. 3. Common operators that are overloaded include +, -, *, /, ++, --, =, etc. This allows user-defined types to be used with operators in the same way as built-in types.

Uploaded by

Dhanraj Kumar
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
You are on page 1/ 41

Operator Overloading

Module II
Operator Overloading
• Closely related to function overloading is operator overloading.
• In C++, you can overload most operators so that they perform special
operations relative to classes that you create.
• When an operator is overloaded, none of its original meanings are lost.
Instead, the type of objects it can be applied to is expanded.
• The ability to overload operators is one of C++'s most powerful
features.
• It allows the full integration of new class types into the programming
environment.
• After overloading the appropriate operators, you can use objects in
expressions in just the same way that you use C++'s built-in data types.
Operator Overloading
• You overload operators by creating operator functions.
• An operator function defines the operations that the overloaded
operator will perform relative to the class upon which it will work.
• An operator function is created using the keyword operator.
• Operator functions can be either members or nonmembers of a class.
• Nonmember operator functions are almost always friend functions of
the class.
• The way operator functions are written differs between member and
nonmember functions.
• Therefore, each will be examined separately, beginning with member
operator functions.
Operator Overloading
• For adding two objects of the same class we can use 3 ways
• d3.addobjects(d1, d2);
• d3 = d1.addobjects(d2);
• can be changed to the much more readable
• d3 = d1 + d2; using operator overloading
• The following operators are not overloaded in C++
• ?: (conditional)
• . (member selection)
•.* (member selection with pointer-to-member)
•:: (scope resolution)
•sizeof (object size information)
Creating a Member Operator Function
• A member operator function takes this general form:
ret-type class-name::operator#(arg-list)
{
// operations
}
Consider the class loc
class loc {
int longitude, latitude;
public:
loc() {}
loc(int lg, int lt) {
longitude = lg;
latitude = lt; }
void show() {
cout << longitude << " ";
cout << latitude << "\n"; } ……..};
member operator function
loc operator+(loc op2); //binary plus means obj1=obj1+obj2
loc operator*(int val); //multiply with integer
loc operator-(loc op2); //binary minus
void operator-(); //unary minus
loc operator=(loc op2); //assignment
loc operator++(); // prefixincrement
loc operator++(int); // postfix increment
loc operator—(); //prefix decrement
loc operator—(int);//postfix decrement
// Overload + for loc.
Overloading Binary Operators loc loc::operator+(loc op2)
#include <iostream> {
using namespace std; loc temp;
class loc { temp.longitude = op2.longitude + longitude;
int longitude, latitude; temp.latitude = op2.latitude + latitude;
public: return temp;
loc() {} }
loc(int lg, int lt) { int main()
longitude = lg; {
latitude = lt; } loc ob1(10, 20), ob2( 5, 30),ob3;
void show() { ob1.show(); // displays 10 20
cout << longitude << " "; ob2.show(); // displays 5 30
cout << latitude << "\n"; } ob1 = ob1 + ob2;// ob1=ob1.operator+(ob2);
loc operator+(loc op2); Ob3=ob2+ob1;//ob2.operator+(ob1);
}; ob3=ob1+ob2;//display
ob1.show(); // displays 15 50
return 0;
}
// Overload binary - for loc. // Overload unary minus - for loc.
loc loc::operator-(loc op2) loc loc::operator-( )
{ {
loc temp; longitude = -longitude;
// notice order of operands latitude = -latitude;
temp.longitude = longitude - op2.longitude; return (*this);
temp.latitude = latitude - op2.latitude; }
return temp; int main()
} {
loc ob1(10, -20),b2;
loc ob1(20,30),ob2(10,20); ob1.show(); // displays 10 20
ob1=ob1-ob2; b2=-ob1;
b2.show(); // displays -10 20
ob1.show();
}
// Overload assignment for loc. // Overload prefix ++ for loc.
loc loc::operator=(loc op2) loc loc::operator++()
{ {
longitude = op2.longitude; longitude++;
latitude = op2.latitude; latitude++;
return *this; // i.e., return object that return *this;
generated call }
} int main(){
int main(){ loc ob1(10, 20);
loc ob1(10, 20),ob2(1,2),ob3(90,90); ++ob1;
ob1 = ob2 =ob3; // multiple assignment ob1++;//error
ob1.show(); // displays 90 90 ob1.show(); // displays 11 21
ob2.show(); // displays 90 90 return 0;
return 0; }
}
Creating Prefix and Postfix Forms of the Increment and Decrement
Operators
• C++ allows you to explicitly create separate prefix and postfix versions
of increment or decrement operators.
• To accomplish this, you must define two versions of the operator++( )
function.
• One is defined as shown in the foregoing program.
• The other is declared like this:
loc operator++(int x);
// in main
ob++;
//prefix int main(){
loc loc::operator++() loc ob1(10, 20),ob2(1,2),ob3;
{ ++ob1;//ob1.operator++();
longitude++; ob1.show();
latitude++; ob2++;//ob2.operator++(int);
return *this; ob2.show();
} ob3=++ob1;
//postfix ob3.show();
loc loc::operator++(int) ob1.show();
{ ob3=ob2++;
loc temp=*this; ob3.show();
longitude++; ob2.show();
latitude++;
return temp;
}
loc loc::operator*(int val) // in main
{ ob3=ob3*5;//ob3=ob3.operator*(5);
longitude=longitude*val; ob3.show();
latitude=latitude*val; ob3=5*ob3;//error
return *this; }
}
Friend Function
• Friend functions play a very important role in operator overloading by
providing the flexibility denied by the member function of a class.
• They allow overloading of stream operators(<< or >>)
• The only difference between friend function and a member function is
that the friend function requires the arguments to be explicitly passed
to the function and processes them explicitly
• where as the member function considers the first argument implicitly.
Using friend function
#include <iostream>
using namespace std;
class loc {
int longitude, latitude;
public:
loc() {longitude=0;latitude=0;}
loc(int lg, int lt)
{
longitude = lg;
latitude = lt;
}
void show()
{
cout << longitude << " ";
cout << latitude << "\n";
}
Using friend function operator overloading
friend loc operator+(loc op1,loc op2); //binary plus means obj1=obj1+obj2
friend loc operator*(loc op1,int val); //multiply with integer
friend loc operator-(loc op1,loc op2); //binary minus
friend void operator-(loc &op1); //unary minus
friend loc operator+(loc op1, int op2);
friend loc operator+(int op1, loc op2);

friend loc operator++(loc &op1); // prefixincrement


friend loc operator++(loc &,int); // postfix increment
friend loc operator--(loc &); // prefixdecrement
friend loc operator--(loc &,int); // postfix decrement
friend istream & operator >>(istream &in, loc &ob);
friend ostream & operator <<(ostream &out, loc &ob);
};
Using friend function overloading of binary +
loc operator+(loc op1,loc op2)
{
loc temp;
temp.longitude = op1.longitude + op2.longitude;
temp.latitude = op1.latitude + op2.latitude;
return temp;
}
//ob1=operator+(ob1,ob2);
//In main
{
loc ob1(10,10),ob2(20,20);
ob1=ob1+ob2;
}
Using friend function overloading of binary -
loc operator-(loc op1,loc op2)
{
loc temp;
temp.longitude = op1.longitude - op2.longitude;
temp.latitude = op1.latitude - op2.latitude;
return temp;
}

// ob2=ob1-ob2;
Using friend function overloading of binary *
loc operator*(loc op1,int val) int main()
{ {
loc temp;
temp.longitude = op1.longitude*val; loc ob1(20,20);
temp.latitude = op1.latitude * val; ob1=ob1*2;
return temp; ob1=2*ob1;
}
loc operator*(int val,loc op1)
{ }
loc temp;
temp.longitude = op1.longitude*val;
temp.latitude = op1.latitude * val;
return temp;
}
Using friend function overloading of unary -
void operator-(loc &op1)
{
op1.longitude=-op1.longitude;
op1.latitude=-op1.latitude;
}

//main
-ob1;
ob1.show();
Using friend function overloading of unary ++( prefix increment)
loc operator++(loc &op1)
{
op1.longitude=op1.longitude+1;
op1.latitude++;
return op1;
}
//in main
++ob1;
Using friend function overloading of unary ++(postfix increment)
loc operator++(loc &op1,int)
{
loc temp(op1);
op1.longitude=op1.longitude+1;
op1.latitude++;
return temp;
}
//In main
ob2=ob++; //10 10
ob2.show(); //10 10
ob.show(); // 11 11
Using friend function overloading of unary –( prefix decrement)
loc operator--(loc &op1)
{
--op1.longitude;
--op1.latitude;
return op1;
}
Using friend function overloading of unary –(postfix decrement)
loc operator--(loc &op1,int)
{
loc temp=op1;
op1.longitude--;
op1.latitude--;
return (temp);
}
Overloading extraction operator >> using friend function
Overloading extraction operator >> using friend function
istream & operator >>(istream &in, loc &ob)
{
cout<<"Enter longitude and latitude"<<endl;
in>>ob.longitude;
in>>ob.latitude;
return in;
}
//In main
loc ob3
cout<<"enter values for ob3"<<endl;
cin>>ob3; // operator>>(cin,ob3);
Overloading of Insertion operator << using Friend function
Overloading of Insertion operator << using Friend function
ostream & operator <<(ostream &out, loc &ob)
{
out<<"The objects member variables are"<<endl;
out<<ob.longitude<<"-"<<ob.latitude<<endl;
return out;
}
//in main
cout<<ob3;// operator<<(cout,ob3); as ob3.show();
cout<<ob1;
Manipulation of sting using operator Overloading
Header files String1 :: String1(){
using namespace std; cout << "<Inside default constructor.>"<<endl;
class String1{ len = 0;
char *name; name = new char[1];
int len; name[0] = '\0‘;
public: }
String1(); String1 :: String1(const char *s)
String1(const char *s); {
String1(const String1 &s); cout << "<Inside parameterised
String1 operator=(const String1 &s); constructor.>"<<endl;
String1 operator+(const String1 &s); len=strlen(s);
bool operator == (String1 ss) ; name = new char[len+1];
void display() const; strcpy(name,s);
}; }
Manipulation of sting using operator Overloading
String1 String1::operator=(const String1& s) {
String1 :: String1(const String1& s) { cout<<"Inside assignment ..."<<endl;
len=strlen(s.name); len=strlen(s.name);
name = new char[len+1]; name=new char[len+1];
strcpy(name,s.name); strcpy(name,s.name);
} return s;
void String1 :: display() const }
{ Instead of strcpy() also can write
cout<<"name: " <<name<<" "<<"lenth: for (int i=0; i<size; i++) {
"<<len<<endl; name[i] = s[i];}
} name[size] = '\0';
String1 :: ~String1()
{
delete [] name;
}
String Manipulation
Note : String1 *p1=new String1(“Institute");
int main (){ String1 *p2=new String1(*p1);
String1 s2; p1->display();
String1 s1(“Heritage”); p2->display();
s1.display(); *p2=*p1;// what happened
String1 s3=s1; p1->display();
s3.display(); p2->display();
String1 s4(s3); p2=p1; // what happened
s4.display(); delete p1;
s2=s4; delete p2;
s2.display();
Assignment operator overload ( two way)
bool String1 :: operator == (String1 ss) { bool String1 :: operator == (String1 &s){
return ( strcmp(name, ss.name)==0 ) ? true : false; if (this->len != s.len) {
} return false;
Note }
int main (){ for (int i=0; i<s.len; i++) {
String1 s1(“Heritage”); if ((this->len)[i] != (s.len)[i]) {
s1.display(); return false;
String1 s2=s1; }
s2.display(); }
if (s1 == s2) { return true;
cout << “Strings are equal\n"; }
} else {
cout << “Strings are not equal\n";
………..
}
Overloading + operator for sting concatenation
String operator+(const String& s1, const Note :
String& s2) int main (){
{ String1 str1(“Heritage”);
String temp; String1 str2(“Institute”),str3;
temp.len=s1.len+s2.len; str3=str1+str2;
temp.name=new char[temp.len+1]; str3.display();
strcpy(temp.name,s1.name); …………..
strcat(temp.name,” “);
strcat(temp.name,s2.name);
return temp;
}
Overloading new and delete
• 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 only 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
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.
Overloading new and delete
void *operator new(size_t size) • In the new overloaded function, dynamic
memory is allocated through new operator, but
{ it should be global new operator otherwise it
cout<<"overloading new"<<endl; will go in recursion
• void *p = new String();
void *p=::new String();
• // this will go in recursion as new will be
Or overloaded again and again
//void*p=malloc(size); for global • void *p = ::new String(); // this is correct
overloading
return p; • For global overloading
}
//in main • //in main
String *p=new String("Technology"); int *p=new int[5];
char *s=new char[20];
p->display();
Overloading new and delete
• Syntax
void operator delete(void *)
• The function receives a parameter of type void* which has to be
deleted. Function should not return anything.

void operator delete(void *p)


{
cout<<"overloading delete"<<endl;
free(p) ; or
::delete p;
}
//in main
delete p;
Main function
int main() str4.display();
{ if(str1==str2)
String str1("Heritage"),str3,str4; cout<<"two string equal"<<endl;
cout<<"Str1 is: "<<endl; else
str1.display(); cout<<"two string not equal"<<endl;
String str2="Institute"; if(str3==str4)
cout<<"Str2 is: "<<endl; cout<<"two string equal"<<endl;
str2.display(); else
str3=str1+str2; cout<<"two string not equal"<<endl;
cout<<"str3 is"<<endl; return 0;
str3.display(); }
str4=str3;
Overloading subscript or array index [] operator
• The subscript operator [] is normally used to access array elements.
This operator can be overloaded to enhance the existing functionality
of C++ arrays.
• Following are some useful facts about overloading of [].
• Overloading of [] may be useful when we want to check for index out
of bound.
• We must return by reference in function because an expression like
“arr[i]” can be used an lvalue.
Overloading array index [] operator
#include <iostream> int &operator[](int i) {
using namespace std; if( i > SIZE ) {
const int SIZE = 10; cout << "Index out of bounds" <<endl;
return arr[0];
class Array { }
private: return arr[i];
int arr[SIZE]; }
};
public: int main() {
Array() { Array A;
int i; cout << "Value of arr[2] : " << A[2] <<endl;
for(i = 0; i < SIZE; i++) { cout << "Value of arr[5] : " << A[5]<<endl;
arr[i] = i; cout << "Value of arr[12] : " << A[12]<<endl;
} return 0;
} }
Overloading function call ()
loc operator()(int a,int b) void operator()(int i,int j,int k) {
{
loc ob1; arr[0]=arr[0]+i;
ob1.longitude =longitude+ a*100; arr[1]=arr[1]+j;
ob1.latitude = latitude+b*100; arr[2]=arr[2]+k;
return ob1;
} }
//In main //in main
loc ob1(10, 20),ob3; Array A;
ob3=ob3(10,10); A(10,20,30);
ob3.show();// cout<<A[0]<<endl;//10
cout<<A[1]<<endl;//21
cout<<A[2]<<endl;//32
Question Overload * to multiply two matrices (using dynamic memory allocation)

class Matrix{ ~Matrix (){


int rows;
int cols; cout<<"destructor"<<endl;
int **Mat; for(int i =0;i<rows;i++)
public: delete [] Mat[i];
Matrix(){cout<<"default"<<endl;rows=0;cols=0;} delete [] Mat;
Matrix (const int rows, const int cols); }
Matrix(const Matrix &o); };
Matrix &operator=(const Matrix &o );
Matrix operator *(const Matrix &o);
friend ostream &operator<<(ostream &os, Matrix &m);
friend istream &operator>>(istream &os, Matrix &m);
Matrix::Matrix(const int row,const int col ) Matrix::Matrix(const Matrix &o)
{ {
cout<<“ Parameterized constructor"<<endl; cout<<"copy constructor"<<endl;
rows=row; cols=o.cols;
cols=col; rows=o.rows;
Mat=new int* [rows]; Mat=new int* [o.rows];
for(int i =0;i<rows;i++) { for(int i =0;i<o.rows;i++) {
Mat[i]=new int[cols]; Mat[i]=new int[o.cols];
} }
for(int i=0;i<rows;i++) for(int i=0;i<o.rows;i++)
for(int j=0;j<cols;j++) for(int j=0;j<o.cols;j++)
Mat[i][j]=0; Mat[i][j]=o.Mat[i][j];
}
}

Do remaining part of code to execute the program successfully.

You might also like