aravindakasukurthi.files.wordpress.com viewoperator overloading. the ability to overload operators...

23
Operator Overloading The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators, you can use objects in expressions in expressions in just the same way that you use C++’s built-in data types. You overload operators by creating operator functions. An operator function defines the operations that the overload 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. Creating a member operator function ret-type classname :: operator#(arg-list) { //operations } The # is a place holder. When you create an operator function, substitute the operator for the #. Example: For + ------------ operator + When you are overloading a unary operator, arg-list will be empty. When you are overloading binary operators, arg-list will contain one parameter. operator+() has only one parameter even though it overloads the binary + operator. The operand on the left side of the + is passed implicitly to the function through the this pointer. The operand on the right is passed in the parameter op2. When binary operators are overloaded, it is the object on the left that generates the call to the operator function.

Upload: vokhuong

Post on 23-Apr-2018

218 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

Operator Overloading

The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators, you can use objects in expressions in

expressions in just the same way that you use C++’s built-in data types. You overload operators by creating operator functions. An operator function defines the operations that the overload 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.

Creating a member operator function

ret-type classname :: operator#(arg-list){

//operations}The # is a place holder.When you create an operator function, substitute the operator for the #.

Example: For + ------------ operator +

When you are overloading a unary operator, arg-list will be empty. When you are overloading binary operators, arg-list will contain one parameter. operator+() has only one parameter even though it overloads the binary + operator. The operand on the left side of the + is passed implicitly to the function through the

this pointer. The operand on the right is passed in the parameter op2. When binary operators are overloaded, it is the object on the left that generates the

call to the operator function. It is common for an overloaded operator function to return an object of the class it

operates upon. By doing so, it allows the operator to be used in larger expressions. It is important to understand that an operator function can return any type and that

the type returned depends solely upon your specific application. Operator+() function does not modify either operand. Because, the traditional use of

the + operator does not modify either operand.Example 4+5=9

Example program:

#include<iostream>using namespace std;class opload1{

Page 2: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

int a,b;public:void read();opload1 operator+(opload1);void display();

};void opload1 :: read(){

cout<<"Enter a,b\n";cin>>a>>b;

}opload1 opload1 :: operator+(opload1 ob){

opload1 op3;op3.a=a+ob.a;op3.b=b+ob.b;return op3;

}void opload1 :: display(){

cout<<"a="<<a<<"\tb="<<b<<endl;}main(){

opload1 op1,op2,op3;op1.read();op2.read();op3=op1+op2;op3.display();

}

In C++, if the = is not overloaded, a default assignment operation is created automatically for any class you define.

The default assignment is simply a member-by-member, bitwise copy. The operator = () function returns *this, which is the object the generated the call. This arrangement is necessary is you want to be able to use multiple assignment

operations such as this:

ob1=ob2=ob3; //multiple assignment

opover opover :: operator=(opover op){

a=op.a;b=op.b;return *this; //return object that generated call.

Page 3: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

}

To stay consistent with their original meanings.

Creating prefix and postfix forms of the increment and decrement operators

opover operator++(); //opover is class name //overload prefix ++ for opover. If the ++ preceeds its operand, the operator ++() function is called. If the ++ follows the operand, the operator ++ (int x) is called and x has the value

zero.

//prefix increment syntaxtype increment(){

//body of prefix operator}//postfix increment syntaxtype operator ++(int x){

//body of postfix operator}

Here, x is dummy argument which is used to differentiate between pre & post increment or decrement operators.

Example program:

// Overload pre, post increment#include<iostream>using namespace std;class opover{

public:int a;float b;opover(){

a=0;b=0;

}opover(int i,float j){

a=i;b=j;

Page 4: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

}opover operator++(){

opover t;t.a=++a;t.b=++b;return t;

}opover operator++(int x){

opover t;t.a=a++;t.b=b++;return t;

}void display(){

cout<<"\na="<<a<<"\tb="<<b<<endl;}

};main(){

opover op1(4,5.6),op2(6,3.7),op3;op1.display();op2.display();

cout<<"After Pre increment\n";op3=++op1;op3.display();op1.display();

cout<<"After Post increment\n";op3=op1++;op3.display();op1.display();

}

Overloading the shorthand operators

You can overload any of C++’s “shorthand” operators, such as +=, -=, …

opload1 opload1 :: operator+=(opload1 ob){

a=ob.a+a;

Page 5: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

b=ob.b+b;return *this;

} When overloading one of these operators, keep in mind that you are simply

combining an assignment with another type of operation.

Example program:

// Overloading Shorthand Assignment operators#include<iostream>using namespace std;class opover{

public:int a;float b;opover(){

a=0;b=0;

}opover(int i,float j){

a=i;b=j;

}opover opover :: operator+(opover op)

{opover t;t.a=a+op.a;t.b=b+op.b;return t;

}opover operator+=(opover op){

a=a+op.a;b=b+op.b;return *this;

}void operator-=(opover op){

a=op.a-a;b=op.b-b;

}

Page 6: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

void display(){

cout<<"\na="<<a<<"\tb="<<b<<endl;}

};main(){

opover op1(4,5),op2(6,8);op1.display();op2.display();op1+=op2+op2;op1.display();op2-=op1;op2.display();

}

Operator overloading using a Friend function

You can overload an operator for a class by using a nonmember function, which is usually a friend of the class.

Since a friend function is not a member of the class, it does not have a this pointer.

Therefore an overloaded friend operator function is passed the operands explicitly.

When overloading a binary operator using a friend function, the left operand is passed in the first parameter and the right operand is passed in the second parameter.

Example:

friend opload operator+(opload,opload); //Now a friend

definition

opload1 operator+(opload1 op1,opload1 op2){opload1 t;t.a=op1.a+op2.a;t.b=op1.b+op2.b;return t;}

Example program:

// Overload + using friend

Page 7: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

#include<iostream>using namespace std;class opover{

int a;float b;public:opover(){

a=0;b=0;

}opover(int i,float j){

a=i;b=j;

}friend opover operator+(opover,opover);void display(){

cout<<"\na="<<a<<"\tb="<<b<<endl;}

};opover operator+(opover ob1,opover ob2){

opover t;t.a=ob1.a+ob2.a;t.b=ob1.b+ob2.b;return t;

}main(){

opover op1(4,5.6),op2(6,3.7),op3;op1.display();op2.display();op3=op1+op2;op3.display();

}

There are some restrictions that apply to friend operator functions:

1. You may not overload the =, (), [], or -> operators by using a friend function.2. When overloading the increment or decrement operators, you will need to use a

reference parameter when using a friend function.

Page 8: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

3. Because friend functions do not have this pointers.

Some operators cannot be overloaded by using member functions:

1. . (dot) operator2. :: (scope resolution) operator3. .* (pointer to class member) operator4. ?: (Ternary) operator

Using a friend to overload ++ or --

To overload increment or decrement operators using friend function you must pass the operand as a reference parameter. This is because friend functions do not have this pointer.

This causes any changes made to the parameter inside the function to affect the operand that generated the call.

Example program:

#include<iostream>using namespace std;class opover{

int a;float b;public:opover(){

a=0;b=0;

}opover(int i,float j){

a=i;b=j;

}friend opover operator++(opover&);friend opover operator--(opover&,int);void display(){

cout<<"\na="<<a<<"\tb="<<b<<endl;}

};opover operator++(opover &ob){

Page 9: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

++ob.a;++ob.b;return ob;

}opover operator--(opover &ob,int x){

ob.a--;ob.b--;return ob;

}main(){

opover op1(4,5.6),op2(10,7.8),op3;op1.display();++op1;op1.display();op2.display();op2--;op2.display();

}

Friend operator functions to add flexibility

In many cases whether we overload an operator by using member operator function or friend operator function makes no functional difference.Whenever a binary operator is overloaded by member operator function the object on the left side of operator should be an object of the class.Assume a class defines a member operator+() function that adds an object of the class with an integer. If ob is an object of the class then the expression ob+10 is valid but the expression like 10+ob is invalid.The solution to the above problem is to overload the operator by using frien function. Therefore both the operations object+integer and integer+object are valid.

Example:

100+ob1; // this is possible with friend function only.

Example program from class notesor

#include<iostream>using namespace std;class complex

Page 10: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

{int real;int imag;public:complex(){}complex(int x,int y){real=x;imag=y;}friend complex operator+(complex c,int x);friend complex operator+(int x,complex c);void display();};

complex operator+(complex c,int x){complex temp;temp.real=c.real+x;temp.imag=c.imag+x;return temp;}complex operator+(int x,complex c){complex temp;temp.real=x+c.real;temp.imag=x+c.imag;return temp;}void complex::display(){cout<<real<<"+i"<<imag;}main(){complex c1(1,2),c2(2,3),c3,c4;c3=c1+10;cout<<"\n addition=";c3.display();c4=10+c2;cout<<"\n 10+c2=";c4.display();}

Page 11: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

Output:Addition of c1+10=11+i12Addition of 10+c2=12+i13

Overloading new, delete

It is possible to overload new and delete. You might choose to do this if you want to use some special allocation method.

For example, you may want allocation routines that automatically begin using a disk file as virtual memory when the heap has been exhausted.

The skeletons for the functions that overload new and delete are shown here:

// Allocate an object.void *operator new(size_t size){ /* Perform allocation. Throw bad_alloc on failure. Constructor called automatically. */

return pointer_to_memory;}

// Delete an object.void operator delete(void *p){

/* Free memory pointed to by p. Destructor called automatically. */}

The type size_t is a defined type capable of containing the largest single piece of memory that can be allocated. (size_t is essentially an unsigned integer.)

The parameter size will contain the number of bytes needed to hold the object being allocated. This is the amount of memory that your version of new must allocate.

The overloaded new function must return a pointer to the memory that it allocates. Beyond these constraints, the overloaded new function can do anything else you

require. When you allocate an object using new (whether your own version or not), the object's constructor is automatically called.

The delete function receives a pointer to the region of memory to be freed. It then releases the previously allocated memory back to the system. When an object is deleted, its destructor is automatically called.

Example Program:

// Overloading new, delete operators#include<iostream>

Page 12: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

using namespace std;class student{

char name[20];int regdno;public:student(){

strcpy(name,"\0");regdno=0;

}student(char str[20],int r){

strcpy(name,str);regdno=r;

}void display(){ cout<<"\nMy name is "<<name<<"\tRegdno is "<<regdno<<"\n";}void *operator new(size_t size){

void *p;cout<<"\nOverloaded new operator size="<<size<<"\n";p=malloc(size);return p;

}void operator delete(void *p){

cout<<"\nOverloaded delete operator\n";free(p);

}};main(){

student *stu;stu = new student("abcd",1001);stu->display();delete stu;

}

Overloading new, delete for arrays

// new [] overloading Example program:

Page 13: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

#include<iostream>using namespace std;class myclass{

int a,b;public:myclass(){

a=b=0;}myclass(int i,int j){

a=i;b=j;

}void read(){

cout<<"enter a,b\n";cin>>a>>b;

}void *operator new[](size_t size){

void *p;cout<<"new [] size="<<size<<endl;p=malloc(size);return p;

}void operator delete [](void *p){

free(p);}void *operator new(size_t size){

void *p;cout<<"new size="<<size<<endl;p=malloc(size);return p;

}void operator delete(void *p){

free(p);}void display(){

Page 14: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

cout<<"a="<<a<<"\tb="<<b<<"\n";}

};main(){

myclass *p1,*p2;p2=new myclass(100,200);p2->display();p1=new myclass[4];for(int i=0;i<4;i++)p1[i].read();for(int i=0;i<4;i++)p1[i].display();delete p2;delete [] p1;

}

Overloading some special operators

C++ defines array subscripting, function calling, and class member access as operations. The operators that perform these functions are the [ ], ( ), and –>, respectively. One important restriction applies to overloading these three operators: They must be nonstatic member functions. They cannot be friends.

1. Overloading [] (index or subscript operator)

In C++, the [ ] is considered a binary operator when you are overloading it. Therefore,the general form of a member operator[ ]( ) function is as shown here:

type class-name::operator[](int i){// . . .}

Example program:

#include<iostream>using namespace std;class indexop{

int p[10];public:indexop()

Page 15: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

{

}void read(int);int operator[](int i){

return p[i];}

};void indexop :: read(int n){

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

cout<<"Enter val\n";cin>>p[i];

}}

main(){

indexop iop1;int n;cout<<"enter n\n";cin>>n;iop1.read(n);for(int i=0;i<n;i++)cout<<iop1[i]<<"\t"; // call of [] operator

}

// Index operaor with reference

#include<iostream>using namespace std;int n;class indexop{

int p[10];public:indexop(){

}int &operator[](int i){

return p[i];

Page 16: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

}void display(){

for(int i=0;i<n;i++)cout<<p[i]<<"\t";

}};

main(){

indexop iop1;cout<<"enter n\n";cin>>n;for(int i=0;i<n;i++){

int v;cout<<"enter v\n";cin>>v;iop1[i]=v;

}iop1.display();

}

2. Overloading () (function call operator)

Example program:

#include<iostream>using namespace std;class marksclass{

int regdno;float marks;public:marksclass(int r,float m){

cout<<"Constructor is called\n";regdno=r;marks=m;

}marksclass operator()(int r,float m){

cout<<"Operator function is called \n";regdno=r;

Page 17: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

marks=m;return *this;

}void display(){

cout<<"Regdno "<<regdno<<" got "<<marks<<"\n";}

};main(){

marksclass stumarks(1001,67);stumarks.display();stumarks(1205,86); // this is the function call () operator callstumarks.display();

}

3. Overloading ->

The –> pointer operator, also called the class member access operator, is considereda unary operator when overloading. Its general usage is shown here:

object->element Here, object is the object that activates the call. The operator–>( ) function must

return a pointer to an object of the class that operator–>( ) operates upon. The element must be some member accessible within the object.

Example:

#include <iostream>using namespace std;class myclass{int a,b,sum;public:void read(){cout<<"\n enter numbers";cin>>a>>b;}void total(){sum=a+b;}void show(){cout<<"sum="<<sum;

Page 18: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

}myclass *operator->() {return this;}};int main(){myclass ob;ob->read();ob->total();ob->show();return 0;}

4. Overloading the comma operator

The comma is a binary operator. The rightmost value becomes the result of the comma operation.

Example program from notes or

#include <iostream>using namespace std;class loc {int longitude, latitude;public:loc() {}loc(int lg, int lt) {longitude = lg;latitude = lt;}void show() {cout << longitude << " ";cout << latitude << "\n";}loc operator+(loc op2);

loc operator,(loc op2);};// overload comma for locloc loc::operator,(loc op2){loc temp;temp.longitude = op2.longitude;temp.latitude = op2.latitude;cout << op2.longitude << " " << op2.latitude << "\n";return temp;

Page 19: aravindakasukurthi.files.wordpress.com viewOperator Overloading. The ability to overload operators is one of C++’s most powerful features. After overloading appropriate operators,

}// Overload + for locloc loc::operator+(loc op2){loc temp;temp.longitude = op2.longitude + longitude;temp.latitude = op2.latitude + latitude;return temp;}int main(){loc ob1(10, 20), ob2( 5, 30), ob3(1, 1);ob1.show();ob2.show();ob3.show();cout << "\n";ob1 = (ob1, ob2+ob2, ob3);ob1.show(); // displays 1 1, the value of ob3return 0;}