Operating overloading

advertisement
Learning Objectives
•
•
•
•
Fundamentals of Operator Overloading.
Restrictions of Operator Overloading.
Global and member Operator.
Overloading Stream-Insertion and Stream-Extraction
Operators.
• Overloading Unary Operators.
• Overloading Binary Operators.
Operating overloading
•
•
•
•
•
C++ enables the programmer to overload most operators to be sensitive to the
context in which they are used. The compiler generates an appropriate function or
method call based on the operator's use.
To overload an operator, write a function definition; the function name must be
the keyword operator followed by the symbol for the operator being overloaded.
To use an operator on class objects, that operator must be overloaded - with two
exceptions. The assignment operator (=) may be used with two objects of the
same class to perform a default memberwise assignment without overloading. The
address operator (&) also can be used with objects of any class without
overloading; it returns the address of the object in memory.
The point of operator overloading is to provide the same concise expressive power
for user-defined data types that C++ provides with its rich collection of operators
that work on built-in types.
Operator overloading is not automatic - the programmer must write operator
overloading functions to perform the desired operations. Sometimes these
functions are best made methods; sometimes they are best as friend functions.
Restrictions on Operator Overloading
+
-
*
/
%
^
&
|
~
!
=
<
>
+=
-=
*=
/=
%=
^=
&=
|=
<<
>>
>>=
<<=
==
!=
<=
>=
&&
||
++
--
->*
,
->
[]
()
new
delete
new[]
delete[]
Fundamentals of Operator Overloading
• Process that enables C++’s operators to work with class objects.
• C++ has ability to provide the operators with a special meaning for a data.
The mechanism of giving such special meanings to an operator is known
as operator overloading.
• C++ can overload the entire C++ operator except following:
1. Class member access operator (. )
2. Scope resolution operator (::)
3. Size operator (sizeof)
4. Conditional operator (? :)
Why do we need operator overloading? Do we really need it?
• For instance, compare the following syntaxes to perform addition of two
objects a and b of a user-defined class Fraction (assume class Fraction
has a member function called add() which adds two Fraction objects):
c = a.add (b);
c = a+b;
• 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.
• If you use the operator without providing the mechanism of how these
operators are going to perform with the objects of our class, you will get
error message
Fundamentals of Operator Overloading
• Process that enables C++’s operators to work with class objects.
• C++ has ability to provide the operators with a special meaning for a data.
The mechanism of giving such special meanings to an operator is known
as operator overloading.
• C++ can overload the entire C++ operator except following:
1. Class member access operator (. )
2. Scope resolution operator (::)
3. Size operator (sizeof)
4. Conditional operator (? :)
Why do we need operator overloading? Do we really need it?
• For instance, compare the following syntaxes to perform addition of two
objects a and b of a user-defined class Fraction (assume class Fraction
has a member function called add() which adds two Fraction objects):
c = a.add (b);
c = a+b;
• 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.
• If you use the operator without providing the mechanism of how these
operators are going to perform with the objects of our class, you will get
error message
Defining operator overloading
• 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.
• The general format of member operator function is:
return type class name :: operator op(arglist)
{
function body // task defined
}
Example:
#include <iostream>
using namespace std;
class Overload
{
public:
int num;
Overload() {num=0; }
void operator*();
};
void Overload::operator*( )
{
num*=num;
cout<<"\n Num ="<<num;
num+=1;
}
int main( ) {
OUTPUT:
Overload obj;
Num =0
*obj;
Num =1
*obj;
-------------------------------return 0;
Process exited after 0.01693 seconds with return value 0
Press any key to continue . . .
}
#include<iostream>
using namespace std;
class xyz{
int x, y, z;
public:
void get(){
cout<<"XYZ please\n";
cin>>x>>y>>z; }
void disp(){
cout<<x<<y<<z<<endl; }
friend void operator-(xyz &S);//pass by reference
};
void operator-(xyz &S){
S.x=-S.x;//object name must be used as it is a friend function
S.y=-S.y;
S.z=-S.z;
}
int main(){
xyz s1;
s1.get();
OUTPUT:
cout<<"BEFORE OVERLOADING\n";
XYZ please
s1.disp();
456
cout<<"AFTER OVERLOADING \n";
BEFORE OVERLOADING
-s1;
456
s1.disp();
AFTER OVERLOADING
return 0;
-4-5-6
}
-------------------------------Process exited after 4.041 seconds with return value 0
Press any key to continue . . .
Overloading Stream-Insertion and Stream-Extraction
Operators
• Overloaded << and >> operators
– Overloaded to perform input/output for user-defined types
– Left operand of types ostream & and istream &
– Must be a non-member function because left operand is not an
object of the class
– Must be a friend function to access private data members
Example:
#include <iostream>
using namespace std;
class Distance
{
private:
int feet;
// 0 to infinite
int inches;
// 0 to 12
public:
// required constructors
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
friend ostream &operator<<( ostream &output, const Distance &D )
{
output << "F : " << D.feet << " I : " << D.inches;
return output;
}
friend istream &operator>>( istream &input, Distance &D )
{
input >> D.feet >> D.inches;
return input;
}
};
int main()
{
OUTPUT:
Distance D1(11, 10), D2(5, 11), D3;
Enter the value of object :
cout << "Enter the value of object : " << endl; 45 6
First Distance : F : 11 I : 10
cin >> D3;
Second Distance :F : 5 I : 11
cout << "First Distance : " << D1 << endl;
Third Distance :F : 45 I : 6
cout << "Second Distance :" << D2 << endl;
cout << "Third Distance :" << D3 << endl;
-------------------------------return 0;
Process exited after 5.81 seconds with return value 0
Press any key to continue . . .
}
Cont…
• Operators that cannot be overloaded
• .
.* :: ?:
• It is not possible to change the “arity” of an
operator ie. The numbers of operands an
operator takes.
• Overloaded unary operators remain unary
operators and overloaded binary operators
remain binary operators.
Cont…
• Operator overloading is not automatic
• Must write operator-overloading functions to perform the desired
operations
• Call on an object of the class and operate on that object
• To use an operator on an object of a class, must define overloaded
operator functions for that class
• 1. The assignment operator(=) may be used with most classes to
perform memberwise assignment of the data members – each data
member is assigned from the assignment’s “source”(on the right)
object to the “target” object (on the left).
• Memberwise assignment is dangerous for classes with pointer
members, so well’l explicitly overload the assignment operator for
such classes
• The address (&) operator returns a pointer to the object; this
operator also can be overloaded
Cont…
• The comma operator evaluates the expression
to its left then the expression to its right ,
and returns the value of the latter expression.
• This operator also can be overloaded.
• The ability to provide the operators with a
special meaning for a data type and this
mechanism of giving such special meanings to
an operator is known as operator overloading.
Cont…
• Syntax:
• Returntype classname::operator op(arg-list)
• {
Functionbody // task defined
}
Where returntype is the type of value returned by
the specified operation and op is the operator being
overloaded. The op is preceded by the keyword
operator. Operator op is the function name.
Cont…
• The process of overloading involves the following
steps:
• 1. First, create a class that defines the datatype
that is to be used in the overloading operation.
• 2.Declare the operator function operator op() in
the public part of the class. It may be either a
member function or a friend function.
• 3.Define the operator function to implement the
required operations.
Overloading stream insertion and a
stream extraction operators
• Fundamental types using the stream extraction
operator>>
• Stream insertion operator<<
• The class libraries provide with c++ compilers
overload these operators to process each
fundamental type, including pointers and C- like
char * strings.
• The stream insertion and stream extraction
operators also can be overloaded to perform
input and output for user-defined types.
Cont…
•
•
•
•
•
•
•
•
Example:
#ifndef PHONE NUMBER_H
#define PHONE NUMBER_H
#include <iostream>
Using std::ostream;
Using std::istream;
#include<string>
Using std:: string;
Cont…
• Class phonenumber
• {
• Friend ostream &operator<<(ostream &, const
phonenumber &);
• Friend istream &operator>>(istream&, phone
number &);
• Private:
•
string areacode;
•
string exchange;
Cont…
•
•
•
•
•
•
•
•
•
String line;
};
*endif
# phonenumber.cpp
#overloaded stream insertion and stream
extraction operators
# for class phonenumber
#include<iomanip>
Using std::setw;
#include “phonenumber.h”
Cont…
•
•
•
•
//overloaded stream insertion operator; cannot be
//a member function if we would like to invoke it with
// cout << some phonnumber;
Ostream &operator<<(ostream &output, const
phonenumber &number)
• {
output<<“(“ <<number.areacode<<“)”
<< number.exchange<<“_” <<number.line;
return output;
}
Cin>> some phonnumber
Istream &operator >> (istream &input, phonenumber &number)
Cont…
• {
input.ignore();
input>>setw (3)>> number.areacode;
input.ignore(2);
input>>setw (3)>>number.exchange;
input>>ignore();
input>>setw (4)>> number.line;
Return input;
}// end function operator>>
Cont…
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
#include <iostream>
Using std :: cout;
Using std :: cin;
Using std :: endl;
# include “phonenumber.h”
Int main()
{
Phonenumber phone;
Cout<<“enter phone number in the form (123) 456-7890:”<<endl;
Cin >>phone;
Cout<<“The phone entered was:”;
Cout<<phone invokes operator<< by implicitly issuing
Cout<<phone<<endl;
Return 0;
}
//end main
Cont…
• Output:
• Enter phone number in the form (123) 4567890:
• (800) 555-1212
• The phone number entered was:(800) 5551212
Cont…
•
•
•
•
•
•
•
•
Unary operators
Op x or x Op
Binary operators
X op y
Friend functions
Operator op (x)
Member functions
Operator op (x.y)
Global and member operators
• Operators that are loaded as member
functions
• (),[], -> any other assignment operators, the
operator overloading function must be
declared as a class member.
• For other operators, the operator overloading
functions can be class members or global
functions.
Cont…
• Operators as member functions and global
functions
• When an operator function is implemented as
a member function, the leftmost operand
must be an object(or a reference to an object)
of the operator’s class.
Overloading stream-insertion and
stream –extraction operators
• The overloaded stream insertion operator(<<) is
used in an expression in which the left operand
has type ostream &, as in cout<< class object.
• To use the operator, the right operand is an
object of a user –defined class, it must be
overloaded as a global function.
• For a member function operator << have to be a
member of the ostream class.
• Istream &,as in cin>> class object and the right
operand is an abject of a user-defined class – it
must be a global function.
Cont…
• Is able to input and output the fundamental types
using the stream extraction operator>>
and the stream insertion operator<<.
• The class libraries provided with compiler
overload these operators to process each
fundamental type, including pointers and strings
• The stream insertion and stream extraction
operators also can be overloaded to perform
input and output for user defined types.
Cont…
•
•
•
•
•
•
•
•
•
•
•
•
Example:
# include (iostream>
# include<string>
Class phonenumber
{
friend ostream &operator<<(ostream &,const phonenumber &);
friend istream &operator>>(istream &, phonenumber & );
Private:
string areacode;
string exchange;
string line;
};
• #endif
Overloading unary operators
• A unary operator for a class can be overloaded as a non
static member function with no arguments or as a global
function with one argument
• That argument must be either an object of the class or a
reference to an object of the class.
• Example:
• Class string
• {
• Public:
bool operator!() const;
…..
};
Overloading binary operators
• A binary operator can be overloaded as a non –
static member function with one argument or as
a global function with two arguments(one of
those arguments must be either a class object or
a reference to a class object).
• Class string
• Public:
bool operator<(const stsring &)const;
…
};
Cont…
•
•
•
•
Example: unary operator
# include <iostream.h>
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;
}
Cont…
•
•
Void space :: display (void)
{
cout << x<<“”;
cout<< y <<“”;
cout<< z<< “\n”;
}
Void space :: operator-() //defining operator-()
{
X = -x;
Y = -y;
Z = -z;
}
Main()
{
space s;
s.getdata(10, -20, 30);
cout << “s : “;
s.display();
-s;
//activates operator –()
Cout<<“S : “ ;
S.Display ();
}
Output:
S : 10 -20 30
S : -10 20 -30
Cont…
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Example :
Over loading Binary operators:
# include <iostream.h>
Class complex
{
float x;
//real part
float y;
// Imaginary part
Public:
complex ()
complex(float real, float imag}
[ x= real; y=imag;]
complex operator+(complex);
void display (void);
};
Complex complex :: operator + (complex c)
{
Complex temp; //temporary
temp.x = x + c.x; //float addition
temp.y = y + c.y; //float addition
return (temp);
Cont…
•
•
Void complex :: display (void)
{
cout<<x<< “ + j” <<y<<“\n”;
}
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();
}
Output
C1 = 2.5 + j3.5
C2 = 1.6 + j2.7
C3 = 4.1 + j6.2
Download