COEN244: Operator overloading -...
Transcript of COEN244: Operator overloading -...
COEN244: Operator overloading
Aishy Amer
Electrical & Computer Engineering
OutlineFriend functions
Operator notation in C++
Why operator overloading?
What can/cannot be overloaded?
Two ways to overload: member andnon-member operators
Unary operator overload
Binary operator overload
Multi-Overloading
Assignment operator versusCopy constructor
Some rules to overloading
Chain statements
Special operators:[]() + + −− <<>>
A complete example with member functions
A complete example with friend functions
c© A. Amer Operator Overloading 1
Introduction
Compiler identifies a function by its interface consisting ofits namenumber of its parameterstype of its parametersorder of its parameters
Recall:private members can be accessed/modified only whileINSIDE *a* member function
c© A. Amer Operator Overloading 2
Friend functions
A friend function is a function that is not a member function ofa particular class but still can access its non-public members
For an external function to access the private and protectedmembers of a class:
it needs to be a friend of the class that defines thesemembersThe keyword friend is used
c© A. Amer Operator Overloading 3
Friend functions
Exampleclass C i r c l e {
private :i n t rad ius , x , y ;
public :. . .i n t Area ( ) ; / / Member f u n c t i o n to Compute areaf r iend C i r c l e copy ( const C i r c l e &) ; / / Fr iend f u n c t i o n
} ;
i n t C i r c l e : : Area ( ) { return PI∗ rad ius∗ rad ius ; }
C i r c l e copy ( const C i r c l e& src ) { return C i r c l e ( src . rad ius , s rc . x , s rc . y ) ; }
/ / UsageC i r c l e a (10 ,3 ,6 ) , b ; cout << a . area ( ) ;
b = copy ( a ) ; cout << b . Area ( ) << ’ \ n ’ ;
c© A. Amer Operator Overloading 4
Friend functions
Use member functions instead of friend functions whenpossible
In some case, friend functions can be very usefule.g., operator overloading
Friend functions are also used to specify friend classesTo declare all member functions of a class A as friends of another class B
use the following declaration in the definition of the class A: friend class B;
The friend relationship is neither symmetric nor transitiveIf a class A is a friend of class B it does not imply that B is a friend of A
Note that friend functions break encapsulationTherefore, pick your friend classes carefully!
We can also specify only the member functions that we want them to be friends insteadof all the member functionsfriend void B::print(A &);
c© A. Amer Operator Overloading 5
Notation
C++ operators: + ∗ / + + >><< ...
Binary operator z=x+y; cout<<z;Unary operator z++;
x += y;x is left-hand (LH) objecty is right-hand (RH) objectx is target objecty is the source object
Recall: an object is implicitly accessed via the this pointer
⇒ Use this pointer to implicitly access the target object
c© A. Amer Operator Overloading 6
Why operator overloading?
C++ goal:
treat programmer-defined and built-in types equally
provide an intuitive interface to USERS of your class
Solution: Extending built-in operators so that the same
expression syntax with operator can be applied to objects
c© A. Amer Operator Overloading 7
Why operator overloading?
C++ goal:
treat programmer-defined and built-in types equally
provide an intuitive interface to USERS of your class
Solution: Extending built-in operators so that the same
expression syntax with operator can be applied to objects
Examples:i n t a =5 ,b =3; a +=b ;time3 = time1 + time2 ;tim3 ++; cout<< time3 ;Complex x ( 2 0 , 4 0 ) , y ( 3 0 , 5 0 ) ;x +=y ;cout<<x ; / / => x =(20+30) + i (40+50)
c© A. Amer Operator Overloading 7
Two ways to overload
You may overloadmember & non-member (e.g., friend) functions of a class
Member function:Prototype Syntax :< re turn_type > operator <op> ( <RHobject>& ) ;Example : void operator +=( t ime &) ;
Non-member function: (normally declared as a friend)Prototype Syntax :f r iend <re turn_type > operator <op> ( < LHobject >&, <RHobject >&);Example : f r iend void operator << ( iost ream &, t ime &) ;
c© A. Amer Operator Overloading 8
Overloading using member functions
Uses this pointer to implicitly access the source objectOnly object for unary operatorsLeft-hand object for binary operators
Syntax:<re turn_type > operator <op> ( <RHobject>& ) ;
Example:void Complex : : operator += ( const Complex &b ) { / / t a r g e t ob jec t changes
r e a l = r e a l + b . r e a l ; / / add to the r e a l component o f the t a r g e timag = imag + b . imag ; / / add to the imag component o f the t a r g e t
}/ / Test ingComplex x (20 ,40) , y (30 ,50 ) ;x +=y ; / / x i s the t a r g e t ob jec t , y i s the source ob jec t
c© A. Amer Operator Overloading 9
Recall: Friend functions
A friend function is a a NON-member function thata class permits to have access to an object’s private datamembers
Friend functions are NOT member functions of the class butfree functions which have been given access to a class’s datamember
Friend functions are implemented without the scoperesolution operator
c© A. Amer Operator Overloading 10
Overloading as non-member (friend) function
Should only be done when necessary
Accepts all object parameters through argument list
Syntax:f r iend <re turn_type > operator <op> ( < LHobject >&, <RHobject >&);
Example:/ / Dec la ra t i onf r iend ostream& operator <<(ostream&, const Complex&) ;
/ / Implementat ionostream& operator <<(ostream& os , const Complex& Z) {
os << ( (Z . r e a l ) ? Z . r e a l : ’ ’ ) ;i f (Z . imag ) os << " + i " << Z . imag ;return os ;
}
c© A. Amer Operator Overloading 11
Why to use friend functions
1. To overload operators that have another class as the leftoperand, e.g., <<
2. To permit operators to be commutative such as inComplex a , c ; c= 5+a ; / / c =?. opera tor +(a ) ;
3. To make some function calls more attractive such as inTime t1 , t2 ;i f ( t1 . compareTo ( t2 ) == 0) . . .
==> i f ( compareTo ( t1 , t2 ) == 0) . . .
4. Friend function can be more efficient:they can avoid some of the costs of going through memberfunctions
c© A. Amer Operator Overloading 12
Operator overloading: Example
class Time {f r iend ostream& operator <<(ostream&, const Time &) ;public :
. . . / / cons t ruc to r svoid set ( i n t h=0 , i n t m=0 , i n t s =0) ;. . .void operator +=(Time &t ) ; / / Overload the b inary += opera torvoid operator + + ( ) ; / / Overload the unary ++ p r e f i x opera tor
. . .private : i n t hour , minute , second ;
} ;
/ / D e f i n i t i o n o f the overloaded b inary += opera torvoid Time : : operator +=(Time &t ) {
/ / Use the set f u n c t i o n to take care o f the a d d i t i o nset ( hour + t . hour , minute + t . minute , second + t . second ) ;
}
c© A. Amer Operator Overloading 13
Operator overloading: Example
/ / D e f i n i t i o n o f the overloaded unary ++ p r e f i x opera torvoid Time : : operator ++() {
/ / Use the set f u n c t i o n to take care o f the incrementset ( hour , minute , second +1) ;
}. . ./ / Use of the overloaded opsTime t , p (13 ,0 ,10 ) ;for ( i n t i =0; i <N; i ++) {
t ++;t . d i sp lay ( ) ;
}t +=p ;
c© A. Amer Operator Overloading 14
What can/cannot be overloaded?
Operator overloading:the ability to re-define built-in C++ operators to manipulateuser-defined objects
Can be:+ − ∗ / % ^ & | ~ != < > += −= ∗= /= %=^= &= |= << >> >>= <<= == != <= >=&& | | ++ −− −>∗ , −>[ ] ( )new delete new [ ] delete [ ]
Cannot be:. .∗ : : ? : sizeof/ / .∗ i s p o i n t e r to member
Why would you need to overload the “cannot be” operators?
c© A. Amer Operator Overloading 15
Two types of operators to overload
C++ operators: + ∗ / + + >><< ...
Binary operator z=x+y; cout<<z;Unary operator z++;
c© A. Amer Operator Overloading 16
Unary operator overload
Member unary Ops:Syntax : < re turn_type > operator <op symbol> ( ) ;
Example : void operator + + ( ) ; / / Overload the unary ++ p r e f i x opera tor
Number o f parameters accepted : none
Friend unary Ops:Syntax : f r iend <re turn_type > operator <op symbol> ( < RHobject >&);
Example : f r iend void operator ++( Rat iona l &x ) ;
Number o f parameters accepted : one for unary opera tors
c© A. Amer Operator Overloading 17
Binary operator overload
Member binary Ops:Syntax : < re turn_type > operator <op symbol >(<RHobject >&);
Example : void operator +=(Time &t ) ; / / Overload the b inary += opera tor
Number o f parameters accepted : one
Friend binary Ops:Syntax : f r iend <re turn_type > operator <op symbol >(< LHobject >&, <RHobject >
Example : f r iend void operator += ( Rat iona l &x , const Rat iona l &y ) ;
Number o f parameters accepted : two for b inary opera tors
c© A. Amer Operator Overloading 18
Overloading: Multi-Overloading
Can we do the following?/ / Test ingComplex Z1 ( 1 , 1 ) , Z2 ( 0 . 5 , 0 .707) , r e s u l t ( 0 , 0 ) ;double x = 1.264 ;r e s u l t = Z1 + Z2 ; / / yesr e s u l t = Z1 + x ; / / yesr e s u l t = x + Z1 ; / / ???? wi th member f u n c t i o n s ?
c© A. Amer Operator Overloading 19
Overloading: Multi-Overloading
class Complex {f r iend Complex operator +( double , Complex& ) ;public :
void Complex ( double = 0 , double = 0 ) ;Complex operator +( Complex& ) ;Complex operator +( double ) ;
private : double rea l , imag ;} ;
Complex Complex : : operator +( Complex& RHZ ){ return Complex ( r e a l + RHZ. rea l , I + RHZ. imag ) ; }
Complex Complex : : operator +( double x ){ return Complex ( r e a l + x , imag ) ; }
Complex operator +( double x , Complex& RHZ ){ return Complex ( RHZ. r e a l + x , RHZ. imag ) ;
c© A. Amer Operator Overloading 20
Operator overloading: Example
/ / L i s t i n g 10.4 Overloaded opera tor f u n c t i o n sclass Complex { / / programmer−def ined data type
private :double rea l , imag ; / / p r i v a t e data
public :. . .Complex ( double r , double i ) ; / / genera l cons t ruc to rComplex operator +( const Complex &b ) const ; / / no change to t a r g e tvoid operator += ( const Complex &b ) ; / / t a r g e t ob jec t changesvoid operator += ( double b ) ; / / t a r g e t ob jec t changesvoid operator + ( ) const ; / / no change to t a r g e t
} ; / / end of c lass Complex
c© A. Amer Operator Overloading 21
Operator overloading: Example
Complex : : Complex ( double r , double i ) / / genera l cons t ruc to r{ r e a l = r ; imag = i ; }
Complex Complex : : operator +( const Complex &b ) const / / over load +{
return Complex ( r e a l + b . rea l , imag + b . imag ) ; / / no change to t a r g e t}
Note: "Complex (real + b.real, imag + b.imag);" creates anunnamed object by calling the general constructor Complex(...)
c© A. Amer Operator Overloading 22
Operator overloading: Example
/ / Note b . r e a l : a p r i v a t e data member can only be accessed/ / from w i t h i n the class , i . e . , the data can be accessed or/ / modi f ied only wh i le INSIDE ∗a∗ member f u n c t i o n o f the c lass .
/ / over load +=void Complex : : operator += ( const Complex &b ) { / / t a r g e t ob jec t changes
r e a l = r e a l + b . r e a l ; / / add to the r e a l component o f the t a r g e timag = imag + b . imag ; / / add to the imag component o f the t a r g e t
}
/ / over load += againvoid Complex : : operator += ( double b ) / / t a r g e t ob jec t changes
{ r e a l += b ; } / / add to r e a l component o f the t a r g e t
/ / over load + again −− p r e f i x ( see l a t e r )/ / opera tor + ( ) means p r e f i x => +z ; opera tor +( i n t ) means p o s t f i x => z+void Complex : : operator + ( ) const / / no change to t a r g e t
{ cout << " ( " << r e a l << " , " << imag << " ) " << endl ; } / / t a r g e t ’ s f i e l d s
c© A. Amer Operator Overloading 23
Operator overloading: Example
/ / Test ingComplex x (20 ,40) , y (30 ,50) , z1 ( 0 , 0 ) , z2 ( 0 , 0 ) ; / / def ined , i n i t i a l i z e dcout << " Value of x : " ; +x ; / / same as x . opera tor + ( ) ;cout << " Value of y : " ; y . operator + ( ) ; / / anyth ing goesz1 = x . operator +( y ) ; / / use i n the f u n c t i o n c a l lcout << " z1 = x + y : " ; +z1 ;z2 = x + y ; / / same as z2=x . opera tor +( y ) ;cout << " z2 = x + y : " ; +z2 ;z1 += x ; / / same as z1 . opera tor +=(x ) ;cout << " Add x to z1 : " ; +z1 ;z2 += 30 .0 ; / / same as z2 . opera tor += (30 .0 ) ;cout << " Add 30 to z2 : " ; +z2 ;
c© A. Amer Operator Overloading 24
Overloading: really needed?
class Complex {private : . . .public : . . .
} ;
/ / Without opera tor over load ing :Complex Complex add ( const Complex& x , const Complex& y ) ;Complex mul ( const Complex& x , const Complex& y ) ;Complex foo ( const Complex& a , const Complex& b , const Complex& c ){ / / a∗b + b∗c + c∗a
return add ( add ( mul ( a , b ) , mul ( b , c ) ) , mul ( c , a ) ) ;}
/ / With opera tor over load ing :Complex operator+ ( const Complex& x , const Complex& y ) ;Complex operator∗ ( const Complex& x , const Complex& y ) ;Complex f ( const Complex& a , const Complex& b , const Complex& c ){ return a∗b + b∗c + c∗a ; }
c© A. Amer Operator Overloading 25
Overloading: really needed?
This class looks more complex..
But remember: the goal is to make the use of your classeasierit makes life easier for the users of your class, not for thedeveloper of the class!
Remember: in a reuse-oriented ( or OO) language, there willusually be many people who use your class
Your design should favor the many users
c© A. Amer Operator Overloading 26
Overloading object assignment =
The = operator is a method related to a class
If an object is assigned to another object
a member-wise copy is performed
Example:Time t1 (12 , 01 , 30) , t2 ;t2 = t1 ; / / assignment method =/ / t2 gets the values 12 , 01 , 30
Be careful with member-wise copyIf member data is a pointer, the pointer address is copiedthis could be disastrous
c© A. Amer Operator Overloading 27
Overloading object assignment =
If your object has a pointer to memory that was dynamicallyallocated previously, e.g., in the constructor, you will need anoverloaded assignment operator
Typical steps to overload the assignment operator:Make sure you aren’t assigning an object to itselfe.g. x = xDelete the associated memoryCopy all the membersReturn *this which is necessary to allow multipleassignment,e.g., x = y = z; → x = (y = z);
c© A. Amer Operator Overloading 28
Overloading =: Example
class Person {private :char∗ name ;i n t i d ;
public :. . .
} ;
/ / Would l i k e toPerson a , b , c ; . . . b=a ; / / a : source ob jec t ; b : t a r g e t ob jec t
c© A. Amer Operator Overloading 29
Overloading =: Example
Person& Person : : operator =( const Person& p ) {i f ( th is != &p ) { / / make sure not same ob jec t
delete [ ] name ; / / f r ee o ld name ’ s memory .
name = new char [ s t r l e n ( p . name ) + 1 ] ; / / get new spacei f ( p == NULL) { / / t e s t f o r success , q u i t i f no memory
cout <<" Person : : opera tor = ( ) : no memory" ;e x i t ( 1 ) ;
}
s t r cpy (name, p . name ) ; / / copy new namei d = p . i d ; / / copy i d
}
return ∗ th is ; / / r e t u r n r e f f o r m u l t i p l e assignment}
c© A. Amer Operator Overloading 30
Overloading =: More Example
/ / an ob jec t i s i m p l i c i t l y accessed v ia the t h i s p o i n t e rClass t r i a n g l e {
/ / assume pt2d ( a po in t i n 2D) i s a c lass def ined p rev ious l yprivate :
pt2d∗ v e r t i c e s ;public :
. . ./ / cons t r uc to r & d e s t r u c t o rt r i a n g l e ( const t r i a n g l e& t ) ; / / copy cons t ruc to rt r i a n g l e operator =( const t r i a n g l e& t ) ; / / assignment opera tor. . . .
} ;
c© A. Amer Operator Overloading 31
Overloading =: More Example
/ / copy assignment opera tort r i a n g l e t r i a n g l e : : operator =( const t r i a n g l e& t ) {
i f ( th is != & t ) / / s e l f−assignment l i k e t = t ?for ( i n t i =0; i <3; i ++)
v e r t i c e s [ i ] = t . v e r t i c e s [ i ] ;return ????? / / what do you t h i n k ? r e t u r n t h i s ; or r e t u r n ∗ t h i s
}
/ / Test ingpt2d p1 (20 ,40) , p2 (30 ,90) , p3 (40 ,10 ) ;t r i a n g l e a ( p1 , p2 , p3 ) , b ;b = a ; / / OK?
c© A. Amer Operator Overloading 32
Copy constructor vs. =
What is the difference between a copy constructor and anoverloaded assignment operator?
A copy constructor:constructs a new object by using the content of the argumentobject
Complex a , c ; / / dec lare a & c c a l l d e f a u l t cons t ruc to r sComplex b=a ; / / dec lare b and copy a to i t by c a l l i n g copy cons t ruc to r
An overloaded assignment operator: assigns the contents ofan existing object to another existing object of the same class
c=a ; / / somewhere i n your program : an overloaded assignment opera tor
c© A. Amer Operator Overloading 33
Outline
Operator notation in C++
Why operator overloading?
What can/cannot be
overloaded?
Two ways to overload:
member and non-member
operators
Unary operator overload
Binary operator overload
Multi-Overloading
Assignment operator versus
Copy constructor
Some rules to overloading
Chain statements
Special operators:
[]() + + −− <<>>
A complete example with
member functions
A complete example with
friend functions
c© A. Amer Operator Overloading 34
Operator overloading: Rules
You can only overload existing C++ built-in operatorscan only redefine existing operators - no making up new ones
You cannot change the meaning of existing operators forbuilt-in types by overloading them for built-in types
You can only overload operators for programmer definedtypes⇒ You can define the meaning of the operator for theprogrammer-defined type
You cannot change the number of operands that the operatortakes
You cannot change the precedence of the operator or itsassociativity
c© A. Amer Operator Overloading 35
Operator overloading: Rules
New behaviors for operators should be consistent with defaultbehavior
At least one operand of any overloaded operator must be ofsome user-defined type (i.e., class)
Make sure the class design support its own methods (e.g.,define constructor)
Use the const keyword for parameters of overloaded operatorfunctions that do not change the value of their parameters
Mark the function as constant if the target object does notchange
The absence of the const keyword is the evidence that thefunction changes the target object
c© A. Amer Operator Overloading 36
Operator overloading: Rules
An overloaded unary operator declared as member functiontakes no parameters, i.e., works on target object
An overloaded unary operator declared as friend functiontakes one parameter which must be object of the same classor a pointer to an object of the class
An overloaded binary operator declared as member functiontakes one parameter:
Target object is always used on left side of operator
Object on right side of operator taken from parameter passed
An overloaded binary operator declared as friend functiontakes two parameters:
1st is on left side of operator & 2nd is on right side of operator
c© A. Amer Operator Overloading 37
Overloading: Chain statements
What does object.method1().method2() means?
First object.method1() is executed
This returns some object which might bea reference to object, i.e., method1() might end with return*this; ORsome other object
Let’s call the returned object objectB
Then objectB becomes the this object of method2()
Examples of method chaining:in the iostream library, e.g., cout << x << y which worksbecause cout << x is a function that returns cout
in assignments x = y = z;
c© A. Amer Operator Overloading 38
Overloading: Chain statements
Recall: After a function return statement, a temporary copy ofthe return value is returned
Complex& Complex : : operator = ( . . . . ) {Complex temp ;/ / r e t u r n temp ;return ∗ th is ;
} / / temp i s destroyed/ / a copy of the r e t u r n ob jec t value i s made/ / t h i s copy i s a v a i l a b l e to the c a l l e r o f the f u n c t i o n
x = y = z; means x = (y = z); //precedence rules of the = Op
Sometime you want: (x = y) = z;Thus (x = y) should return an object if you overload =
cout << x << y; means (cout << x) << y;Recall: Input/Output statements executes from left to right
c© A. Amer Operator Overloading 39
Outline
Operator notation in C++
Why operator overloading?
What can/cannot be
overloaded?
Two ways to overload:
member and non-member
operators
Unary operator overload
Binary operator overload
Multi-Overloading
Assignment operator versus
Copy constructor
Some rules to overloading
Chain statements
Special operators: ⇐
[]() + + −− <<>>
A complete example with
member functions
A complete example with
friend functions
c© A. Amer Operator Overloading 40
Overloading: Insertion/Extraction
The iostream library is an object-oriented library that providesinput and output functionality using streams
A stream is an abstraction that represents a device in whichinput and output operations are performed
A stream can basically be represented as an indefinite sourceor destination of characters
The number of character to be in/output is not needed to beknown in advance
We can simply write characters to the stream or get them untilwe find it convenient or until the source of characters exhausts
c© A. Amer Operator Overloading 41
Overloading: Insertion/Extraction
The streams are generally associated to a physical source ordestination of characters:
Examples: a disk file, the keyboard or a text console, ..
The characters we get or write to/from our abstraction calledstream are physically input/output to the physical device
For example, file streams are C++ objects to manipulate andinteract with filesOnce a file stream is used to open a file, any input or outputoperation performed on that stream is physically reflected inthe file.
c© A. Amer Operator Overloading 42
Overloading: Insertion/Extraction
C++ provides a standard iostream library to work with streams
The iostream library provides us with standard IO-objectssuch as cin, cout, & cerr.
These objects are used to perform input/output operations onthe standard input and output devices
c© A. Amer Operator Overloading 43
Overloading: Insertion/Extraction
The Stream Insertion/Extraction Operators are binaryoperators:
cout << i; with cout as an object of type ostream where<< is an output operatorcin >> j; with cin as object of type istream where >> isinput operatorQuestion: should << or >> be overloaded as a memberfunction of ostream class (e.g., cout.operator << (i);) oras a friend function of ostream (e.g.,operator << (cout, i);?
c© A. Amer Operator Overloading 44
Overloading: Insertion/Extraction
Recall: LH Obj. has to be of the same type as the class weare writing the op for
The LH side is an iostream object
Therefore, we cannot have access to the this pointer if weimplemented the overload using a member function
Thus: stream Insertion/Extraction operators MUST beoverload with non-member functions (i.e. friends)
c© A. Amer Operator Overloading 45
Stream Insertion >> Overload
class Time {f r iend i s t ream& operator >>( is t ream &, Time &) ;public :
void Time ( i n t = 0 , i n t = 0 , i n t = 0 ) ;private :
i n t hour ; i n t min ; i n t sec ;} ;
Time : : Time ( i n t h , i n t m, i n t s ) { hour = h ; min = m ; sec = s ; }
c© A. Amer Operator Overloading 46
Stream Insertion >> Overload
i s t ream& operator >>( is t ream& is , Time& T) {i s >> setw ( 2 ) >> T . hour ; i s . ignore ( ) ;i s >> setw ( 2 ) >> T . min ; i s . ignore ( ) ;i s >> setw ( 2 ) >> T . sec ;return i s ;
}
/ / Use : what the user enters goes to T . hour T . min & T . secTime noon ;cout <<" enter data f o r t ime " ; c in >>noon ;
Note: “cin” and “noon” are objects of different types
c© A. Amer Operator Overloading 47
Stream Extraction << Overload
class Complex {f r iend ostream& operator <<(ostream&, const Complex&) ;public :
void Complex ( double = 0 , double = 0 ) ;private :double rea l , imag ;
} ;
Complex : : Complex ( double re , double im ) { r e a l = re ; imag = im ; }
c© A. Amer Operator Overloading 48
Stream Extraction << Overload
ostream& operator <<(ostream& os , const Complex& Z) {os << ( (Z . r e a l ) ? Z . r e a l : ’ ’ ) ;i f (Z . imag )os << " + i " << Z . imag ;
return os ;}
/ / Test ing :complex a ( 1 , 5 ) ;cout << a ; / / p r i n t s 1 + i 5
Note: “cout” and “a” are objects of different types
c© A. Amer Operator Overloading 49
Overloading: Subscript op. []
Does f() = 7 makes sense? What about a[i] = 7 ? What is []?
c© A. Amer Operator Overloading 50
Overloading: Subscript op. []
Does f() = 7 makes sense? What about a[i] = 7 ? What is []?
Subscript operator [] is used for class Array
It is unique: has an object as its LH operand and a subscriptindex as a RH operand
Prototype Syntax:<re turn type> & operator [ ] ( <index type> ) ;
The operator function takes the implied object and a subscriptindex parameter
Usually returns a reference to the indexed value to allowassignment, e.g. object[2] = 10;
c© A. Amer Operator Overloading 50
Overloading: Subscript op. []
class Array {private :
f l o a t ∗ data ;public :
i n t s ize ( ) const ;f l o a t& operator [ ] ( i n t index ) ;. . .
} ;
f l o a t& operator [ ] ( i n t index ) { return data [ index ] ; }
/ / Test ingArray a ;for ( i n t i = 0 ; i < a . s ize ( ) ; ++ i )
a [ i ] = 7 ; / / This l i n e invokes Array : : opera tor [ ] ( i n t )
c© A. Amer Operator Overloading 51
Overloading: Function call Op. ()
Also called “Parenthesis Op”
The Parenthesis operator gives the user a mean to pass anyparameters to an object and return anything
It is like a function call with no function name
Examples:Complex Z ( 1 , 1 ) ; / / Const ruc tor \ \Complex Z( ’ i ’ ) ; / / Parenthes is Operator/ / pass the charac te r i to the ob jec t Z and do something/ / e . g . , ou tput the values o f t h i s ob jec ts
c© A. Amer Operator Overloading 52
Overloading: Function call Op. ()
class Poin t {private : i n t x , y ;public :
Po in t ( i n t i , i n t j ) { x= i ; y= j ; }Po in t operator ( ) ( i n t a , i n t b )
{ Po in t tmp ; tmp . x = x + a ; tmp . y = y + b ; return tmp ; }Po in t operator ( ) ( i n t a )
{ x = x + a ; y = y + a ; return ∗ th is ; }} ;/ / Usage :
Poin t p (1 , 2 ) ; / / genera l cons t ruc to rPoin t q ( p ) ; / / copy cons t ruc to r
p = q ( 5 , 3 ) ; / / invoke opera tor ( )cout << p << q ; / / p =6 ,5; q =1 ,2
q ( 6 ) ; / / invoke opera tor ( )cout << p << q ; / / p=6 ,5: q=7 ,8
c© A. Amer Operator Overloading 53
Increment/Decrement Op. ++/−−
a++; // post-fix ++a; // pre-fix
When used on their own (as above) the prefix and postfixhave the same effect BUT within an expression there is a bigdifference
Prefix notation will increment the variable BEFORE theexpression is evaluated
Postfix notation will increment AFTER the expressionevaluation
main ( ) { main ( ) {i n t a=1; i n t a=1;cout << " a i s "<< ++a ; cout << " a i s " << a++;
/ / ou tput : 2 / / Output 1cout << " a f t e r : a i s "<< a ; cout << " a f t e r : a i s " << a ;/ / Output : 2 / / Output : 2
} }
c© A. Amer Operator Overloading 54
Increment/Decrement Op. ++/−−
There are two types of increment/decrement: Pre and Post
The syntax for pre-increment/decrement is the same as theusual operator overload
<re turn_type > operator + + ( ) ;
The syntax for post-increment/decrement is:
<re turn_type > operator ++( i n t ) ;
int is used to only indicate that the operator is postfixOtherwise how would the compiler distinguish the twofunctions?
Complex Complex : : operator + + ( ) ;Complex Complex : : operator ++( i n t i ) ;
c© A. Amer Operator Overloading 55
Increment/Decrement Op ++/−−
Examples:Complex Complex : : operator ++() { / / p r e f i x as i n ++z
re ++; im++ / / increment both componentsreturn ∗ th is ;
}
Complex Complex : : operator ++( i n t i ) { / / p o s t f i x as i n z++Complex temp=∗ th is ;re ++; im++ / / increment both components
return temp ;}
/ / UseComplex aa =5.0 ; / / aa=Complex ( 5 . 0 ) ;Complex bb=++aa ; / / bb=Complex ( 6 , 1 ) , aa=Complex (6 ,1 )Complex cc=aa++; / / cc=Complex (6 ,1 ) aa=Complex (7 ,2 )
c© A. Amer Operator Overloading 56
Operator overloading: Destructor?
Quiz 1: Can I overload the destructor of a class?
c© A. Amer Operator Overloading 57
Operator overloading: Destructor?
Quiz 1: Can I overload the destructor of a class?
NO. A class can have only one destructor
You never explicitly call a destructor (almost never)
Quiz 2: In which order are objects destroyed?
Objects are destroyed in the reverse order they are declared
c© A. Amer Operator Overloading 57
Outline
Operator notation in C++
Why operator overloading?
What can/cannot be
overloaded?
Two ways to overload:
member and non-member
operators
Unary operator overload
Binary operator overload
Multi-Overloading
Assignment operator versus
Copy constructor
Some rules to overloading
Chain statements
Special operators:
[]() + + −− <<>>
A complete example with
member functions
A complete example with
friend functions
c© A. Amer Operator Overloading 58
Overloading: Complete example with member functions
/ / L i s t i n g 10.6 Class Rat iona l t h a t supports mixed types i n expressions .class Rat iona l {
private :long nmr , dnm; / / p r i v a t e datavoid normal ize ( ) ; / / p r i v a t e member f u n c t i o n
public :Ra t iona l ( long n=0 , long d=1) / / general , conversion , d e f a u l t cons t r uc to r{ nmr = n ; dnm = d ;
this−>normal ize ( ) ; }Ra t iona l operator + ( const Rat iona l &x ) const ; / / constant t a r g e tRat iona l operator − ( const Rat iona l &x ) const ;Ra t iona l operator ∗ ( const Rat iona l &x ) const ;Ra t iona l operator / ( const Rat iona l &x ) const ;void operator += ( const Rat iona l &x ) ; / / t a r g e t changesvoid operator −= ( const Rat iona l &x ) ;void operator ∗= ( const Rat iona l &x ) ;void operator /= ( const Rat iona l &x ) ;
c© A. Amer Operator Overloading 59
Overloading: Example with member functions
bool operator == ( const Rat iona l &other ) const ; / / constant t a r g e tbool operator < ( const Rat iona l &other ) const ;bool operator > ( const Rat iona l &other ) const ;void show ( ) const ;
} ; / / end of c lass s p e c i f i c a t i o n
Rat iona l Ra t iona l : : operator + ( const Rat iona l &x ) const{ return Rat iona l ( nmr∗x .dnm + x . nmr∗dnm, dnm∗x .dnm ) ; } / / e . g . , 1/4+3/2=14/8
Rat iona l Ra t iona l : : operator − ( const Rat iona l &x ) const{ return Rat iona l ( nmr∗x .dnm − x . nmr∗dnm, dnm∗x .dnm ) ; } / / e . g . , 3/2−1/4=10/8
Rat iona l Ra t iona l : : operator ∗ ( const Rat iona l &x ) const{ return Rat iona l ( nmr ∗ x . nmr , dnm ∗ x .dnm ) ; }
Ra t iona l Ra t iona l : : operator / ( const Rat iona l &x ) const{ return Rat iona l ( nmr ∗ x .dnm, dnm ∗ x . nmr ) ; }
c© A. Amer Operator Overloading 60
Overloading: Example with member functions
void Rat iona l : : operator += ( const Rat iona l &x ) {nmr = nmr ∗ x .dnm + x . nmr ∗ dnm; / / 3 /8+3/2=(6+24)/16=15/8dnm = dnm ∗ x .dnm; / / n1 / d1+n2 / d2 = ( n1∗d2+n2∗d1 ) / ( d1∗d2 )this−>normal ize ( ) ;
}
void Rat iona l : : operator −= ( const Rat iona l &x ) {nmr = nmr ∗ x .dnm − x . nmr ∗ dnm; / / 3 /8+3/2=(6+24)/16=15/8dnm = dnm ∗ x .dnm; / / n1 / d1+n2 / d2 = ( n1∗d2−n2∗d1 ) / ( d1∗d2 )this−>normal ize ( ) ;
}
void Rat iona l : : operator ∗= ( const Rat iona l &x ) {nmr = nmr ∗ x . nmr ; dnm = dnm ∗ x .dnm;this−>normal ize ( ) ;
}
c© A. Amer Operator Overloading 61
Overloading: Example with member functions
void Rat iona l : : operator /= ( const Rat iona l &x ) {nmr = nmr ∗ x .dnm; dnm = dnm ∗ x . nmr ;this−>normal ize ( ) ;
}
bool Rat iona l : : operator == ( const Rat iona l &other ) const{ return ( nmr ∗ other .dnm == dnm ∗ other . nmr ) ; }
bool Rat iona l : : operator < ( const Rat iona l &other ) const{ return ( nmr ∗ other .dnm < dnm ∗ other . nmr ) ; }
bool Rat iona l : : operator > ( const Rat iona l &other ) const{ return ( nmr ∗ other .dnm > dnm ∗ other . nmr ) ; }
void Rat iona l : : show ( ) const{ cout << " " << nmr << " / " << dnm; }
c© A. Amer Operator Overloading 62
Overloading: Example with member functions
void Rat iona l : : normal ize ( ) {/ / p r i v a t e member f u n c t i o n
i f ( nmr == 0) { dnm = 1; return ; }i n t s ign = 1;i f ( nmr < 0) { s ign = −1; nmr = −nmr ; }i f (dnm < 0) { s ign = −s ign ; dnm = −dnm; }
long gcd = nmr , value = dnm; / / s t a r t l ook ing f o r g rea tes t common d i v i s o rwhile ( value != gcd ) / / s top when the GCD i s found
{i f ( gcd > value )
gcd = gcd − value ; / / sub t r ac t smal le r number from the grea te relse value = value − gcd ;
}nmr = s ign ∗ ( nmr / gcd ) ; dnm = dnm/ gcd ; / / denominator i s always p o s i t i v e
}
c© A. Amer Operator Overloading 63
Overloading: Example with member functions
−−>Test ing : now we can work w i th r a t i o n a l numbers as wi th o ther numbersRat iona l a ( 1 , 4 ) , b ( 3 , 2 ) , c , d ;c = a + 5; / / c = 5 + a? l a t e ra . show ( ) ; cout << " + " << 5 << " =" ; c . show ( ) ; cout << endl ;d = b − 1;b . show ( ) ; cout << " − " << 1 << " =" ; d . show ( ) ; cout << endl ;c = a ∗ 7;a . show ( ) ; cout << " ∗ " << 7 << " =" ; c . show ( ) ; cout << endl ;d = b / 2 ;b . show ( ) ; cout << " / " << 2 << " =" ; d . show ( ) ; cout << endl ;c . show ( ) ;c += 3;cout << " += " << 3 << " =" ; c . show ( ) ; cout << endl ;d . show ( ) ;d ∗= 2;cout << " ∗= " << 2 << " =" ; d . show ( ) ; cout << endl ;i f ( b < 2){ b . show ( ) ; cout << " < " << 2 << endl ; }
c© A. Amer Operator Overloading 64
Overloading: Complete example with friend functions
/ / L i s t i n g 10 .7 : Class Rat iona l using f r i e n d f u n c t i o n s/ / to suppor t mixed type expressionsclass Rat iona l {
private :long nmr , dnm; / / p r i v a t e datavoid normal ize ( ) ; / / p r i v a t e member f u n c t i o n
public :Ra t iona l ( long n=0 , long d=1) / / general , conversion , d e f a u l t cons t r uc to r{ nmr = n ; dnm = d ;
this−>normal ize ( ) ; }f r iend Rat iona l operator + ( const Rat iona l &x , const Rat iona l &y ) ;
/ / does t h i s + opera tor handle a l l cases R+W, R+6 , 6+R?/ / Maybe convers ion takes place?
f r iend Rat iona l operator − ( const Rat iona l &x , const Rat iona l &y ) ;f r iend Rat iona l operator ∗ ( const Rat iona l &x , const Rat iona l &y ) ;f r iend Rat iona l operator / ( const Rat iona l &x , const Rat iona l &y ) ;f r iend void operator += ( Rat iona l &x , const Rat iona l &y ) ;
c© A. Amer Operator Overloading 65
Overloading: Example with friend functions
fr iend void operator −= ( Rat iona l &x , const Rat iona l &y ) ;f r iend void operator ∗= ( Rat iona l &x , const Rat iona l &y ) ;f r iend void operator /= ( Ra t iona l &x , const Rat iona l &y ) ;f r iend bool operator == ( const Rat iona l &x , const Rat iona l &y ) ;f r iend bool operator < ( const Rat iona l &x , const Rat iona l &y ) ;f r iend bool operator > ( const Rat iona l &x , const Rat iona l &y ) ;void show ( ) const ;
} ; / / end of c lass s p e c i f i c a t i o n
void Rat iona l : : show ( ) const{ cout << " " << nmr << " / " << dnm; }
void Rat iona l : : normal ize ( ) / / p r i v a t e member f u n c t i o n{ . . . . }
c© A. Amer Operator Overloading 66
Overloading: Example with friend functions
Rat iona l operator + ( const Rat iona l &x , const Rat iona l &y ){ return Rat iona l ( y . nmr∗x .dnm + x . nmr∗y .dnm, y .dnm∗x .dnm ) ; }
Ra t iona l operator − ( const Rat iona l &x , const Rat iona l &y ){ return Rat iona l ( x . nmr∗y .dnm − y . nmr∗x .dnm, x .dnm∗y .dnm ) ; }
Ra t iona l operator ∗ ( const Rat iona l &x , const Rat iona l &y ){ return Rat iona l ( x . nmr ∗ y . nmr , x .dnm ∗ y .dnm ) ; }
Ra t iona l operator / ( const Rat iona l &x , const Rat iona l &y ){ return Rat iona l ( x . nmr ∗ y .dnm, x .dnm ∗ y . nmr ) ; }
void operator += ( Rat iona l &x , const Rat iona l &y ){x . nmr = x . nmr ∗ y .dnm + y . nmr ∗ x .dnm; x .dnm ∗= y .dnm;x . normal ize ( ) ;
}
c© A. Amer Operator Overloading 67
Overloading: Example with friend functions
void operator −= ( Rat iona l &x , const Rat iona l &y ){x . nmr = x . nmr∗y .dnm + y . nmr∗x .dnm; x .dnm ∗= y .dnm;x . normal ize ( ) ;
}void operator ∗= ( Rat iona l &x , const Rat iona l &y )
{x . nmr ∗= y . nmr ; x .dnm ∗= y .dnm;x . normal ize ( ) ;
}void operator /= ( Ra t iona l &x , const Rat iona l &y )
{x . nmr = x . nmr ∗ y .dnm; x .dnm = x .dnm ∗ y . nmr ;x . normal ize ( ) ;
}
c© A. Amer Operator Overloading 68
Overloading: Example with friend functions
bool operator == ( const Rat iona l &x , const Rat iona l &y ){ return ( x . nmr ∗ y .dnm == x .dnm ∗ y . nmr ) ; }
bool operator < ( const Rat iona l &x , const Rat iona l &y ){ return ( x . nmr ∗ y .dnm < x .dnm ∗ y . nmr ) ; }
bool operator > ( const Rat iona l &x , const Rat iona l &y ){ return ( x . nmr ∗ y .dnm > x .dnm ∗ y . nmr ) ; }
c© A. Amer Operator Overloading 69
Overloading: Example with friend functions
/ Test ingRat iona l a ( 1 , 4 ) , b ( 3 , 2 ) , c , d ;c = 5 + a ;cout << " " << 5 << " +" ; a . show ( ) ; cout << " =" ; c . show ( ) ; cout << endl ;d = 1 − b ; / / operator −(Ra t iona l ( 1 ) , b ) ;cout << " 1 −" ; b . show ( ) ; cout << " = " ; d . show ( ) ; cout << endl ;c = 7 ∗ a ; / / opera tor ∗ ( Ra t iona l ( 7 ) , a ) ;cout << " 7 ∗ " ; a . show ( ) ; cout << " = " ; c . show ( ) ; cout << endl ;d = 2 / b ; / / opera tor / ( Ra t iona l ( 2 ) , b ) ;cout << " 2 / " ; b . show ( ) ; cout << " = " ; d . show ( ) ; cout << endl ;c . show ( ) ;c += 3; / / opera tor +=(c , Ra t iona l ( 3 ) ) ;cout << " += " << 3 << " =" ; c . show ( ) ; cout << endl ;d . show ( ) ;d ∗= 2; / / opera tor ∗=(d , Ra t iona l ( 2 ) )cout << " ∗= " << 2 << " =" ; d . show ( ) ; cout << endl ;
c© A. Amer Operator Overloading 70
Overloading: Example with friend functions
i f ( a < 5) cout << " a < 5\ n " ; / / operator <(a , Ra t iona l ( 5 ) ) ;i f (1 < b ) cout << " 1 < b \ n " ; / / operator <( Rat iona l ( 1 ) , b ) ;i f (1 < 5) cout << " 1 < 5\ n " ; / / b u i l t −i n i n e q u a l i t y opera tori f ( d ∗ b − a == c − 1) cout << " d∗b−a == c−1 ==" ;( c − 1 ) . show ( ) ; cout << endl ;
c© A. Amer Operator Overloading 71
Outline
Operator notation in C++
Why operator overloading?
What can/cannot be
overloaded?
Two ways to overload:
member and non-member
operators
Unary operator overload
Binary operator overload
Multi-Overloading
Assignment operator versus
Copy constructor
Some rules to overloading
Chain statements
Special operators:
[]() + + −− <<>>
A complete example with
member functions
A complete example with
friend functions
c© A. Amer Operator Overloading 72
Overloading and class design
First think about what the object logically represents,then about how to physically build it
Design your classes from the outsideinterfaces first, i.e., set of public methods
A good interface provides a simplified view that is expressedin the vocabulary of a user
Example, a linked list:A linked list is sequence of elements – what is it?It is built as a chain of nodes – How it is built?The value in the nodes is solely the responsibility of thelinked list userHow would you design a class LinkedList?Start with what a LinkedList is not how it is physicallybuilt!
c© A. Amer Operator Overloading 73
Overloading and class design
Logical interface/abstraction from the user’s point of view:A → B → C → Doperator++ to go to the next elementa get()/set() to access its value stored in the Nodebegin/end method to go to beginning or end or a listappend method to adds an element after the end
Physical structureThe Heap
4
A DCB
prepointer
head
Length
c© A. Amer Operator Overloading 74
Overloading and class design
A linked list of objects of type Tclass Node {
f r iend class L inkedL i s t ;
private :Node ( const T& elem , Node∗ next = NULL ) ;
T elem ; / / T i s the type of elem such as i n t or f l o a tNode∗ next ;
} ;
c© A. Amer Operator Overloading 75
Overloading and class design
class L inkedL i s t {private :Node∗ const head ; / / dummy head node ; p o i n t e r never changes .i n t l eng th ; / / how many elem are i n l i s t ? (dummy node not counted )Node∗ precPo in te r ; / / po in t s 1 node before l o g i c a l p o s i t i o n o f cpo in te r
public :L i nkedL i s t ( ) ;~ L inkedL i s t ( ) ;
/ / movementbool operator ++() ;bool operator−−() ;void toBegin ( ) ;void toEnd ( ) ;
c© A. Amer Operator Overloading 76
Overloading and class design
/ / s t a t ebool atEnd ( ) const ; / / pre p o i n t e r i s one beyond l a s t element i n l i s t
/ / mutat ionbool set ( const T& elem ) ; / / change elem at p o i n t e rbool i n s e r t ( const T& elem ) ; / / put new elem i n f r o n t o f o ld elembool remove ( ) ; / / remove elem at p o i n t e r ; p o i n t e r moves on to next
/ / i nspec t i oni n t l eng th ( ) const ; / / # elems ( not #nodes ) i n l i s tbool get ( T& elem ) const ; / / r e t u r n elem at p o i n t e r/ / and more . . .
} ;
c© A. Amer Operator Overloading 77