operator overloading. introduction computer is calculating machine. it calculates the data provided...
TRANSCRIPT
Operator Overloading
Introduction
• Computer is calculating machine. It calculates the data provided to it. It performs the various operations on data. So, it requires the operators to specify the type of operations to be carried out.
• Every operation involves one or more data item on which these operators act upon are called operands.
• An expression is defined as a meaningful combination of operators and operands.
• Operators are divided as, Unary operators Binary operators
Introduction
// The + operator with ints.int a = 100;int b = 240;int c = a + b; // c is now 340
// + operator with strings.string s1 = "Hello";string s2 = " world!";string s3 = s1 + s2; // s3 is now "Hello world!“
• In essence, the + operator functions in unique ways based on the supplied data types (strings or integers in this case). When the + operator is applied to numerical types, the result is the summation of the operands. However, when the + operator is applied to string types, the result is string concatenation.
Introduction
• Now, the same “+” is used add two class objects, the compiler will throw an error.
// The + operator with class objects.
employee emp1;employee emp2;employee emp3;
emp3 = emp1 + emp2; // Compilation error.
• If we want to add two class objects then we have to go for operator overloading.
Introduction
• 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.
• Example,int a, b, c;class A{ int x; float y; ………….}A a1, b1, c1;
main(){
c = a + b; // adding two built in variables
c1 = a1 + b1; // adding two user defined variables
}
Introduction
• The main idea behind operator overloading is to use c++ operators with the class objects.
• As, c++ operators are applied to the built-in data types, we can also apply those operators to the class objects.
For eg, the +(additional operator) is used to add two int’s, float or double’s.
• The same + can be used to add two class objects, thereby “+” gets overloaded.
• When a + operator is used with two int’s has different meaning as compared when it is applied to object manipulation. Thus, operator overloading contributes to c++’s extensibility.
Introduction
• The mechanism of giving special meanings to an operator is known as operator overloading.
• We can overload (give additional meaning to ) all the C++ operators except the following:
1. class member access operators( . , .* )2. scope resolution operator( :: )3. size operator( size of() )4. conditional operator( ?: )
• Operator overloading extends the semantics of an
operator without changing its syntax.
Introduction
• The grammatical rules defined by C++ that govern its use such as the, no. of operands, precedence, & associativity of the operator remain the same for overloaded operators.
Eg. The multiplication operator has higher precedence than the addition operator.
NOTE:
1. when an operator is overloaded, its original meaning is not lost.Eg. the operator + which has been overloaded to add two vectors, can still be used to add two integers.
2. Semantics (meaning) can be changed, but it has to retain the predefined logical meaning.
DEFINING OPERATOR OVERLOADING:
• Operator overloading is carried out with the help of special function called operator function.
• An operator function defines the operations that the overloaded operator will perform relative to the class on which it works.
• This function is created using the keyword operator.
• These operator functions may or may not be member functions of the class.
• If it is not a member function, it will be a friend function to the class.
DEFINING OPERATOR OVERLOADING:
SYNTAX:
return-type classname :: operator opr( arglist ){
Function body //task defined}
Where, return type is the data type of the return valueclassname name of the class
:: scope resolution operatoroperator is a keyword
opr c++’s built-in operator(overloaded). It may be unary or binary operator
arg.list list of arg’s to be passedoperator opr function name
DEFINING OPERATOR OVERLOADING:
Eg. 1. void sample :: operator *( sample s1, sample s2 )
{// function body
}Here, * is overloaded to perform multiplication of two objects of class sample.
2. void string :: operator +( string str1, string str2 ) {
// string concatenation }
Here, + is overloaded to add two objects( concatenation ) of class string.
DEFINING OPERATOR OVERLOADING:
• Operator functions must be either member functions or friend functions
The difference between them is that:• A friend function will have only one argument, for unary
operators & two for binary operators.• While a member function has no arguments for unary &
only one for binary operators. • This is because the object used to invoke the member
function is passed implicitly & therefore is available for the member function. This is not in friend function.
Member function
Friend function
Unary operator No argument One argument
Binary operator One argument Two argument
DEFINING OPERATOR OVERLOADING:
• Arguments may be passed either by value or by reference.
• Operator functions are declared in the class using prototype as follows:
vector operator +(vector); vector additionvector operator -(vector); vector minusfriend Vector operator +(vector,vector); vector additionfriend Vector operator -(vector); vector minusvector operator -(vector &a); subtractionint operator = = (vector; comparison
DEFINING OPERATOR OVERLOADING:
steps involved in operator overloading:
• Create a class that defines the data type that is to be used in overloading operation.
• Declare the operator function operator opr( ) in the public part of the class. It may be either a member function or a friend function.
• Define the operator function to implement the required operations.
DEFINING OPERATOR OVERLOADING:
OVERLOADABLE OPERATORS:
The list of c++ operators that can be overloaded are:
1. assignment operator : =2. arithmetic operator : + - * / % += -= /= %=3. relational operator : < <= > >= == !=4. logical operators : ! && ||5. bitwise operators : & | ~ ^ << >> >>= <<= &= |=
^=6. incr & decr operator : ++ --7. special operator : [] ( ) * new new[ ]
delete delete[ ]
• The operators are classified into unary & binary operators based on the number of arguments on which they operate.
• Overloading without explicit arguments to an operator function is known as unary operator overloading & overloading with a single explicit argument is known as binary operator overloading.
OVERLOADING UNARY OPERATORS:
• Syntax for overloading the unary operator
returntype operator operatorsymbol( ){
// body of operator function}
Eg: overloading of unary operators;index operator +( );int operator –( );void operator ++( );void operator –( );int operator *( );
NOTE: Overloaded operator member function of a class can be either defined within the body of a class or outside the body of a class.
OVERLOADING UNARY OPERATORS:
Overloaded operator member function within the body of a class:class myclass{
// class data or function int operator ++( ) //member function
definition {
//body of a function }};
Outside the body of a class:class myclass{ // class data or function int operator ++( ) // prototype definition};// overloaded member function definitionint myclass :: operator ++( ){
// body of a function}
Program to show how the unary minus operator is overloaded.
# include<iostream>class space{
int x;int y;int z;
public: void getdata( int a, int b, int c);void display(void);void operator –( );//overload unary minus
};Void space :: getdata(int a, int b, int c){
x = a;y = b;z = c;
}
void space :: display (void){
cout << x << “ “ ;cout << y << “ “ ;cout << z << “ “ ;
}void space :: operator –( ){
x = -x; y = -y; z = -z;}int main( ){
space S;S.getdata( 10, -20, 30 );S.display( );-S;//activates operator-( )
functionS.display( );return 0;
}Output: 10 -20 30 -10 20 -30
OVERLOADING UNARY OPERATORS:
NOTE:
• The function operator –( ) takes no argument.
• This function changes the sign of data members of the object S.
• Since this function is a member function of the same class, it can directly access the members of the object which activated it.
• If a statement is S2 = -S1; will not work because, the function operator –( ) does not return any value.
• It works if the function is modified to return an object.
OVERLOADING UNARY OPERATORS:
• It is possible to overload a unary minus operator using a friend function as follow:
friend void operator –( space &S) //declaration
void operator –( space &S) // definition{
S.x = -S.x;S.y = -S.y;S.z = -S.z;
}
OVERLOADING UNARY OPERATORS:
NOTE:Overloaded operator functions can be invoked by expressions
for unary operatorsop x or x op
for binary operatorx op y
op x or x op would be interpreted asoperator op( x ) for friend functions.
the expressions x op y would be interpreted as either
x.operator op(y) in member functions or
operator op(x, y) in friend functionswhen both the forms are declared, standard argument
matching is applied to resolve any ambiguity.
OVERLOADING BINARY OPERATORS:
• Operator overloading can be used to overload a binary operator.
• In overloading of binary operators, the left-hand operand is used to invoke the operator function & the right-hand operand is passed as an argument.
Consider, c1, c2 & c3 are objects
The statement c3 = c1 + c2
• The statement is valid & invokes operator+( ) function.
w.k.t a member function can be invoked only by an object of the same class.
Here, object c1 invokes the function & c2 is passed as an argument.
OVERLOADING BINARY OPERATORS:
The above statement is equivalent to
c3 = c1.operator + (c2);
The statement, c3 = c1 +100 is valid
Because the L.H operand is used to invoke a operator function & the R.H value is passed as an argument.
The statement, c3 = 100 + c2 is invalid
Because L.H is value & it cannot invoke a operator function.
OVERLOADING + OPERATOR USING BINARY OPERATORS:
#include <iostream>class complex{
float x; float y; public:
complex( ) { }complex( float real, float imag ){
x = real;y = imag;
}complex operator +( complex );void display( void );
};complex complex :: operator +
(complex c){
complex temp;temp.x = x + c.x;temp.y = y + c.y;
return( temp );}
void complex :: display( void ){
cout << x << “ +i “ << y << “\n”;}
int main( ){
complex c1, c2, c3;c1 = complex( 2.5 , 3.5 );c2 = complex( 1.6 , 2.7 );c3 = c1 + c2;cout << “ c1 = “ ;
c1.display( );cout << “ c2 = “ ;
c2.display( );cout << “ c3 = “ ;
c3.display( );return 0;
}
OVERLOADING BINARY OPERATORS USING FRIENDS:
• Friend functions can also be used for overloading a binary operator.
• The difference between a friend function & member function is that, two arguments are passed explicitly in friend function. While in member function requires only one.
E.g.. complex no. program( discussed in member function) using a friend operator function:
• Replace the member function declaration by the friend function declaration:
I.e., friend complex operator +( complex, complex );
OVERLOADING BINARY OPERATORS USING FRIENDS:
Redefine the operator function as follows:
complex operator +( complex a, complex b){
Return complex(( a.x + b.x ), ( a.y + b.y));}
In this case, the statement ,
c3 = c1 + c2; is equivalent to
c3 = operator +( c1, c2 );
OVERLOADING BINARY OPERATORS USING FRIENDS:
NOTE: • In most cases, the result of friend function or a member
function will be same.
• The use of alternate is that, in certain situations we like to use friend function rather than member function.
I.e., for e.g.
• Consider a situation where we need to use two different types of operand for a binary operator, say, one an object & another a built-in type data as shown:
A = B + 2; or A = B * 2;
Where, A & B are objects of the same class. This will work for a member function.
OVERLOADING BINARY OPERATORS USING FRIENDS:
but the statement,
A = 2 + B; or A = 2 * B;
Will not work.
• Because the left-hand operand which is responsible for invoking the member function should be an object of the same class.
• But the friend function allows both approaches.
Program on scalar multiplication of a vector using overloading operators using friends:
# include <iostream.h> const size = 3; class vector{
int v[size]; public:
vector( ); // constructs null vector vector( int *x ); // constructs null vector
friend operator *( int a, vector b); //friend 1friend vector operator *(vector b, int a);//fri2
friend istream & operator>>(istream &, vector &);
friend ostream & operator<<(ostream &,vector&);
};
vector :: vector ( ){
for( int i = 0; i < size; i++) v[i] = 0;
}
vector :: vector(int *x){
for( int i = 0; i < size; i++) v[i] = x[i];
}vector operator *(int a, vector b){
vector c;for( int i = 0; i < size; i++) c.v[i] = a * b.v[i];
return c;}vector operator *( vector b, int a){
vector c;for( int i = 0; i < size; i++) c.v[i] = b.v[i] * a;
return c;}
Program on scalar multiplication of a vector using overloading operators using friends:
istream & operator >> (istream &din, vector &b)
{for( int i = 0; i < size; i++) din >> b.v[i];return (din);
}ostream & operator << (ostream
&dout, vector &b){
Dout << “ ( “ << b.v[0];for( int i = 0; i < size; i++) dout << “ , “ << b.v[i];dout << “ ) “return (dout);
}
int x[size] = { 2, 4, 6 };
int main( ){ vector m; //invokes constructor 1 vector n = x; //invokes constructor 2 cout << “Enter elements of vector m “ << “\n”; cin >> m; //invokes operator >>( ) function
cout << “m = “<< m<< “\n”; //invokes operator<<( ) vector p , q; p = 2 * m; //invokes friend 1 q = n * 2; //invokes friend 2 cout << “ p = “ << p << “\n”;//invokes operator << cout << “ q = “ << q << “\n”; return 0;}
OVERLOADING BINARY OPERATORS USING FRIENDS:
Enter elements of vector m5 10 5
m = ( 5, 10, 15 )p = ( 10, 20, 30 )q = ( 4, 8, 12 )
The prog. Overloads the operator * two times. In both cases, the functions are explicitly passed two arguments & they invoke overloaded function based on the types of its arguments.
p = 2 * m; equivalent to p = operator *(2, m);q = n * 2; equivalent to q = operator *(n, 2);
OVERLOADING BINARY OPERATORS USING FRIENDS:
vector(); constructs a vector whose elements are all zero.
Thus, vector m; creates a vector m & initializes all its elements to 0.
The construct vector( int *x); creates vector & copies the
element pointed to by the pointer arg.x into it. Therefore, the statements
int x[3] = { 2, 4, 6 };vector n = x;
create n as a vector with components 2, 4 & 6.
OVERLOADING BINARY OPERATORS USING FRIENDS:
NOTE:
m & n are vector variables, used in input & output statement.
Similarly to simple variables this can be done by overloading the operators >> & << using the functions:
friend istream & operator >> (istream &, vector & );friend ostream & operator << (ostream &, vector & );
istream & ostream are classes defined in the iostream.h
file.
RULES FOR OVERLOADING OPERATORS:
• Only existing operators can be overloaded. New operators cannot be created.
• The overloaded operator must have at least one operand that is of user-defined type.
• We cannot change the basic meaning of an operator. Ie., we cannot redefine the plus(+) to subtract one value from the other.
• Overloaded operators follow the syntax rules of the original operators. They cannot be overridden.
• There are some operators that cannot be overloaded.• We cannot use friend functions to overload certain
operators. But, member function can be used to overload them. Ie., = assignment operator ( ) function call operator[ ] subscripting operator
class member access operator
RULES FOR OVERLOADING OPERATORS:
• Unary operators, overloaded by means of a member functions take no explicit arguments & return no explicit values, but those overloaded by means of a friend function, take one reference argument.( the object of the relevant class).
• Binary operators overloaded through a member function to one explicit argument & those which are overloaded through a friend function take two explicit argument.
• When using binary operators overloaded through a member function, the left hand operand must be an object of the relevant class.
• Binary arithmetic operators such as +, -, * & / must explicitly return a value. They must not attempt change their own arguments.
• Operators that cannot be overloadedsize of . .* :: ?:
Overloading new and delete
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. */
}
Overloading new and deleteclass loc {
int longitude, latitude; public:
loc() {}loc(int lg, int lt) {
longitude = lg;latitude = lt;
}void show() {
cout << longitude << " ";
cout << latitude << "\n";}void *operator new(size_t size);void operator delete(void *p);
};
// new overloaded relative to loc.void *loc::operator new(size_t size){ void *p; cout << "In overloaded new.\n"; p = malloc(size); if(!p) { bad_alloc ba; throw ba; } return p;}// delete overloaded relative to loc.void loc::operator delete(void *p){ cout << "In overloaded delete.\n"; free(p);}
Overloading new and deleteint main(){
loc *p1, *p2;try {
p1 = new loc (10, 20); } catch (bad_alloc xa) {
cout << "Allocation error for p1.\n";
return 1;}
try {p2 = new loc (-10, -20);
} catch (bad_alloc xa) {
cout << "Allocation error for p2.\n";
return 1;;}
p1->show();p2->show();
delete p1;delete p2;
return 0;
}
Output from this program is shown here.
In overloaded new.In overloaded new. 10 20 -10 -20In overloaded delete.In overloaded delete.
Overloading [ ]#include <iostream>
class atype {
int a[3];public:
atype(int i, int j, int k) {
a[0] = i;a[1] = j;a[2] = k;
}
int operator[](int i){
return a[i]; }
};
int main(){
atype ob(1, 2, 3);cout << ob[1]; // displays 2
ob[1] = 25; // [] on left of =cout << ob[1]; // now displays
25return 0;
}
Overloading [ ]#include <iostream>class atype{
int a[3];public: atype(int i, int j, int k)
{a[0] = i;a[1] = j;a[2] = k;
}int &operator[](int i){ if(i<0 || i> 2) { cout << "Boundary
Error\n";exit(1);
} return a[i];}
};
int main(){ atype ob(1, 2, 3); cout << ob[1]; // displays 2 cout << " "; ob[1] = 25; // [] appears on left cout << ob[1]; // displays 25 ob[3] = 44; // generates runtime error, 3 out- of-rangereturn 0;}
Overloading the Comma Operator
#include <iostream>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 ; return temp;}
// Overload + for locloc loc::operator+(loc op2){ loc temp; temp.longitude = op2.longitude + longitude; temp.latitude = op2.latitude + latitude; return temp;}
Overloading the Comma Operator
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;
}
This program displays the following output:
10 205 301 1
10 601 11 1
program to create class stack & overload the operators + & -.
#include<iostream.h>#include<conio.h>#include<process.h>class stack{
int stk[' '],top;public:
int n;stack(){
top=-1;}~stack(){}stack operator +(int x);stack operator -();friend ostream &
operator<<(ostream &,stack);};
stack stack::operator +(int x){
if(top==(n-1))cout<<"stack is full";else
stk[++top]=x;return *this;
}
stack stack::operator -(){
if(top==-1)cout<<"stack is empty";elsecout<<"popped element is :
"<<stk[top--];return *this;
}
program to create class stack & overload the operators + & -.
ostream& operator <<(ostream& os,stack s)
{int i;if(s.top==-1) cout<<"stack is empty";elseos<<"The contents of the stack are:";for(i=s.top;i>=0;i--)os<<"\n\n"<<s.stk[i];return os;
}void main(){
int ele,item,ch;stack s1;clrscr();cout<<"enter the size of the stack : ";cin>>s1.n;
while(1){ cout<<"\nSELECT MENU\n\n
1.PUSH\n\n 2.POP\n\n3.DISPLAY\n\ 4.EXIT\n\nENTER YOUR CHOICE :";cin>>ch;
switch(ch) { case 1: cout<<"\nenter the element : ";
cin>>ele;s1=s1+ele;
break; case 2: s1=-s1;break; case 3: cout<<s1;break; case 4: exit(0);
break; default:cout<<"Invalid choices";
break; }
getch(); }}