OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you...

31
OPERATOR OVERLOADING

Transcript of OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you...

Page 1: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

OPERATOR OVERLOADING

Page 2: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• 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.

• After overloading the appropriate operators, you can use objects in expressions just like built in data types. An operator function defines the operations that the overloaded operator will perform relative to the class upon which it will work.

• It means performing an operator to work on operands of types it has not yet been designed to operate. e.g. ‘+’ will work on char, int, float, double. It will not work on our ‘String’ class objects

s1 = s2 + s3; //will not compile

Page 3: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• Operator overloading functions are either member functions or friend functions of that class whose objects are intended as operands of the overloaded operator.

• The names of the operator-overloading functions are composed of the keyword operator followed by the symbol of the operator being overloaded.

< ret_type> operator <op> (<arg_list>) ;//prototype < ret_type> <class_name>::operator<op>(<arg_list>) { // function body }• Member functions that overload operators can be

private, protected or public

Page 4: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• A friend function that overloads a given operator:friend<ret_type>operator<op>(<arg_list>);//prototyp < ret_type> operator<op>(<arg_list>) { // function body }• Example of string class – member functionclass String{ public : String operator + (const String &) const;

//prototype //rest of class String }; String String :: operator +(const String & ss ) const { // function body } //definition

Page 5: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• Then we can use the string object as String s1, s2, s3 ; //String class objects s3 = s2 + s1 ; //call to operator overloading function• If it is a friend function – friend String operator + ( const String &, const String &) ; // prototype String operator +(const String&ss1, const String&ss2) { // function body } //definition• How the compiler interprets the operator-

overloading functions ? s3 =s2 + s1; is interpreted as s3=s1.operator+(s2);

if it is a member function

Page 6: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• If it is a friend function then s3 = operator + (s1, s2) ;• Compiler does not say that invalid operands have

been passed to the operator!• The operator overloading functions can also be

called directly from with in the application programs – the way the compiler interprets it !

s3=s1.operator+(s2); or s3 = operator + (s1, s2) ;• We must note that only the name of the operator

overloading function is unusual. Otherwise, they are implemented just like ordinary member, non-member or friend functions.

Page 7: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• Why friend functions used to overload operators? • Let us consider two classes- class A (we defined)

and class B(an existing class or an intrinsic datatype)• We realize that for some reason only object of class

A will be added to an object of class B to get another object of class A : a2 = b1 + a1;

• Object of class B will not be added to object of class A and b1 will not appear on right of ‘+’

• We have no means of modifying the definition of B• If we define the member function as follows- class A { public : A operator + ( const B & ) ; } ; //will not compile.

Page 8: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• The compiler will interpret the statement a2 = b1 + a1; first as a2 = b1 . Operator +(a1) ; and then as a2 = operator + ( b1 , a1 );• The prototype of the member function satisfies

neither of the two interpretations and compiler will throw an error.

• Declaring the operator overloading function as a friend function with an object of class B as the first formal argument solves this problem

friend A operator + ( const B &, const A &);//PT A operator + ( const B & bb, const A & aa ) { // function body } // defintion

Page 9: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• The compiler throws an ambiguity error if both member function and friend functions are used to overload an operator, because both of them will satisfy calls to the overloaded operator.

Overview of overloading unary and binary operators• Member functions that overload unary operators

take no operands, because the calling object is passed as an implicit parameter

• Friend functions will take one parameter, since the function is invoked without the object reference

• Similar explanation can be extended in case of overloading binary operators – in member and friend functions

Page 10: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• Why are operators overloaded?• The operator-overloading functions can be easily

substituted by member functions or friend functions with ordinary but meaningful and relevant names :

String add(const String & ); //prototype String String :: add(const String & ss ){ }//definition String s1, s2, s3 ; s3 = s1 . add (s2) ; • This is a substitute to the ‘addition’ operator (+) • Operator overloading becomes mandatory under

the following circumstances :

Page 11: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

(i) Objects of the class acquire resources dynamically during runtime and no two objects should share the same copy of the resource:

consider the String class – String s1(“abc”), s2; s2 = s1 ; now both cStr will point to the same block which is

undesirable. Hence we defined a suitable copy constructor. The same factors dictate that a suitable function to overload the assignment operator be defined for the ‘String’

(ii) Objects of the class acquire some resources dynamically during runtime and no two objects should share even different copies of the resource:

Page 12: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• Imagine that there is a class whose objects should not share even separate copies of dynamically allocated resources. This means even statements

o1 = o2 ; // should not compile.• The solution is quite simple. We just declare the

function to overload the assignment operator in the private section of the class. Any use of the assign- ment operator with in a non-member function will launch a call to this function. Since the function is private, a compile-time error is thrown. If a member or friend function uses the assignment operator, then it can not be prevented. But, it can be prevented by not defining the function to overload=

Page 13: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

(iii) Objects need to be passed as parameters in function templates and the operators being used on template class objects with in the template functions should work in the same way on the objects of the class : discussed later

(iv) The default action of the dynamic memory management operators( new and delete ) are unsuitable for the class being designed :

The new operator throws an exception, if it fails to allocate memory by default. This may be undesirable to the class designed. The class designer may need to call a member function for this. Only overloading ‘new’ fulfill the need

Page 14: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

(v) Change in the implementation of the class forces an undesirable change in its interface in turn necessitating the rewriting and recompiling of the application programs

(vi) Overloading provides a better readability of code. o2 = ++o1; better than o2 = o1.pre_fix_increment();Rules for operator overloading

• New operators can not be created : creating new operators (such as **) will produce compile time error. void operator ** ( ); //illegal

• Meaning of the existing operator can not be changed : any operator overloading function should take at least one operand of the class of which

Page 15: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

it is a member or friend. Thus it is not possible to change the manner in which an existing operator works on operands of fundamental types. In member functions it is automatically enforced. In case of friend functions, the library programmer needs to take extra care. Illegal attempt -

friend int operator + (int, int); // error • Some of existing operators can not be overloaded : :: (scope resolution) . (member selection) .*(member selection through pointer to member) ?: (conditional operator) sizeof (size of values) typeid (finding the type of object pointed at)

Page 16: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• Some operators can be overloaded using non-static member functions only: = (assignment operator)

( ) (function operator) [] (subscripting operator) -> (pointer to member access operator) these can not be overloaded using friend or static fn.• Number of arguments that an existing operator

takes can not be changed : statement like void operator / () ; //causes compile time error • overloaded operators can not take default

arguments : void operator / ( int=0 ) ; //causes compile time error

Page 17: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• It is highly imprudent to modify the values of the operands that are passed to the operator

overloading functions. • Considering the String class- (will not compile) String operator + (String &); // prototype String String :: operator + (String & ss) //definition { …. ; this->cStr =NULL; //bug: LH param changed

ss->cStr = NULL; // bug: RH param changed } String operator + (String & const) const ; //correct one the const keyword prevent the bugs and compile.

Page 18: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

Overloading the various operators:• Increment and decrement operator: Considering the ‘Distance’ class, we can overload

the increment operator for objects of the class. If d1 and d2 are objects, then d2 = ++ d1; is interpreted as d2 = d1. operator ++( ) ;

Distance operator + + ( ) ; // prototype Distance Distance :: operator ++ ( ) // fn. definition { return Distance (++iFeet, fInches); }• Above should not be a constant member function • In the function first the iFeet data member of the

calling object gets incremented

Page 19: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• The explicit call to the constructor creates a nameless object by passing the incremented value of ‘iFeet’ and unaltered value of ‘fInches’

• The operator overloading function returns the nameless object thus constructed. If the call is on RHS of assignment operator, the returned object will be copied to the object on the left.

• If we write d2 = d1 + +; d1 should get incremented after copying to d2.

• The compiler interprets as d2 = d1 . Operator ++(0);• It implicitly passes zero as parameter to the call to

the overloading function when the postfix notation is used. If it finds a prototype of exact match,

Page 20: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

it compiles without warnings or errors.• The compiler first looks for a function with an

integer as a formal argument provides us with a solution. Formal parameter is a dummy(nameless)class Distance

{ public : Distance operator + +( ) ; //prefix Distance operator + +(int ) ; //postfix /* rest of class Distance */ }; Distance Distance :: operator + +( ) //prefix { return Distance (++iFeet, fInches) ; } Distance Distance :: operator + +( int ) //postfix { return Distance (iFeet+ +, fInches) ; }

Page 21: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• If we provide an operator overloading function for the ‘increment’ operator in prefix notation, we must provide one for postfix notation also.

• For ‘decrement’ operator – prototype & definitions Distance operator - -( ) ; //prefix Distance operator - -(int ) ; //postfix Distance Distance :: operator - -( ) //prefix { return Distance (- -iFeet, fInches) ; } Distance Distance :: operator - -( int ) //postfix { return Distance (iFeet- -, fInches) ; }

Page 22: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

Overloading the unary minus and plus operator class A { int x ; public : A (int = 0 ) ; A operator - ( ) ; } ; A A :: operator – () //member function { return A ( -x ); }• For friend function friend A operator – ( const A & ) ; //prototype A operator – (const A & Aobj ) //definition { return A(- Aobj. x ) ; }

Page 23: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

Overloading the Arithmetic operators• In a member function, the right hand side operand

of the operator appear in list of formal arguments• In a friend function, both operands will appear

class Distance //overloading thro member function { int iFeet; float finches; public: Distance (const int = 0, const float = 0.0 );

void setFeet(const int=0); int getFeet() const; void setInches(const float=0.0); float getInches() const; Distance operator + (const Distance) const };

Page 24: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

Distance Distance :: operator + (const Distance dd1) { const

return Distance ( iFeet + dd1.iFeet , fInches + dd1.fInches ); } • now we can create objects and call function Distance d1(5,8) , d2(4,6) , d3; d3 = d1 + d2 ;• If we pass 2nd parameter a float value then above

code will not work because d3 = d1 + 4.5 ; will be interpreted as d3 = d1. operator + (4.5) ; and compiler will throw an error. To solve this problem we need to introduce a suitable constructor that converts from float to ‘Distance’ type

Page 25: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

Distance :: Distance (const float p) { iFeet = (int) p; fInches = ( p – iFeet ) * 12 ; }• If the left hand side operator is of float type, then it

should be replaced with a friend function. friend Distance operator + (const Distance, /*prototype */ const Distance ) ; Distance Distance :: operator + (const Distance dd1, { const Distance dd2)

return Distance ( dd1.iFeet + dd2.iFeet , dd1.fInches + dd2.fInches ); } • This will tackle all the three conditions of d1 & d2.

Now if both operands are float type values - then

Page 26: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• The operator overloading mechanism will not be invoked, instead values get added to each other.

d3 = 4.75 + 3.25 ; will turn into d3 = 8.0 ; and the constructor that takes float value as parameter and initializes the object with it will be called. Such a constructor is called implicit constructor.Overloading the Relational operators

• These are binary operators. The syntax is similar to that of the arithmetic binary operator. Considering the class Distance, the function to overload ‘>’enum bool {false, true}; class Distance { … bool operator > (const Distance )const;//prototype};

Page 27: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

bool Distance::operator>(const Distance dd1)const { if(iFeet*12 + fInches > dd1.iFeet*12 + dd1.fInches) return true;

return false; } d1>d2 ; d1>4.5 ;• This will work if RHS operator is a ‘Distance’ object.

If it is a float type value, then it will not compile.• Introducing a suitable constructor will solve the

problem. What about 4.75 >d1 ?• We need to replace it with a friend function

bool operator>(const Distance dd1,const Dist dd2) { if(dd1.iFeet*12 + dd1.fInches > dd2.iFeet*12 + dd2.fInches) return true;

return false; }

Page 28: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• All four possibilities as in ‘+’ operatorOverloading Assignment operator

• It is a binary operator and must be overloaded by a non-static member function only. //prototype

class_name & operator = (const class_name &);• By default, the compiler generates the function to

overload the ‘assignment’ operator if the class designer does not provide one. It carries out a simple member-wise copy.class A { public : A & operator =(const & ); };

A & A :: operator = (const A & rhs) { * this = rhs; return this; }

Page 29: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

• In most cases, the default assignment operator is sufficient. For classes that acquire resources dynamically, default causes problem.

• String s1(“abcd”); String s2= s1; • The conclusion is that the assignment operator

must be defined for a class whom the copy constructor is defined. ExampleString (const String &); // copy constructorString & operator = (const String &); String String :: operator = (const String & ss)

{ if this != &ss) {if(cStr != NULL) {delete[] cStr; cStr = NULL;len=0; }

Page 30: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.

if ( ss.cStr != NULL) { len = ss.len; cStr = new char[len + 1]; strcpy(cStr, ss.cStr) ; } } return *this; }• If LHS.cStr =NULL and RHS.cStr =NULL If LHS.cStr =NULL then the first inner ‘if’ fails and

the corresponding if block does not execute. If RHS.cStr =NULL then the second inner ‘if’ fails and the block does not execute. The entire function does not do anything except that it returns the calling object by reference. The value of LHS operand remains unchanged.

Page 31: OPERATOR OVERLOADING. Closely related to function overloading is - operator overloading. In C++ you can overload most operators so that they perform special.