1 Chapter 8 Operator Overloading Outline 8 1

  • Slides: 33
Download presentation
1 Chapter 8 - Operator Overloading Outline 8. 1 Introduction 8. 2 Fundamentals of

1 Chapter 8 - Operator Overloading Outline 8. 1 Introduction 8. 2 Fundamentals of Operator Overloading 8. 3 Restrictions on Operator Overloading 8. 4 Operator Functions as Class Members vs. Global Functions 8. 5 Overloading Stream-Insertion and Stream-Extraction Operators 8. 6 Overloading Unary Operators 8. 7 Overloading Binary Operators 8. 8 Converting between Types 8. 9 Overloading ++ and -8. 10 Case Study: A Date Class 2003 Prentice Hall, Inc. All rights reserved.

2 8. 1 Introduction • Use operators with objects (operator overloading) – Clearer than

2 8. 1 Introduction • Use operators with objects (operator overloading) – Clearer than function calls for certain classes – Operator sensitive to context • Examples – << • Stream insertion, bitwise left-shift –+ • Performs arithmetic on multiple types (integers, floats, etc. ) • Will discuss when to use operator overloading 2003 Prentice Hall, Inc. All rights reserved.

3 8. 2 Fundamentals of Operator Overloading • Types – Built in (int, char)

3 8. 2 Fundamentals of Operator Overloading • Types – Built in (int, char) or user-defined – Can use existing operators with user-defined types • Cannot create new operators • Overloading operators – Create a function for the class – Name function operator followed by symbol • Operator+ for the addition operator + 2003 Prentice Hall, Inc. All rights reserved.

4 8. 2 Fundamentals of Operator Overloading • Using operators on a class object

4 8. 2 Fundamentals of Operator Overloading • Using operators on a class object – It must be overloaded for that class • Exceptions: – Assignment operator, = • Memberwise assignment between objects – Address operator, & • Returns address of object – Both can be overloaded • Overloading provides concise notation – object 2 = object 1. add(object 2); – object 2 = object 2 + object 1; 2003 Prentice Hall, Inc. All rights reserved.

5 8. 3 Restrictions on Operator Overloading • Cannot change – How operators act

5 8. 3 Restrictions on Operator Overloading • Cannot change – How operators act on built-in data types • I. e. , cannot change integer addition – Precedence of operator (order of evaluation) • Use parentheses to force order-of-operations – Associativity (left-to-right or right-to-left) – Number of operands • & is unitary, only acts on one operand • Cannot create new operators • Operators must be overloaded explicitly – Overloading + does not overload += 2003 Prentice Hall, Inc. All rights reserved.

6 8. 3 Restrictions on Operator Overloading 2003 Prentice Hall, Inc. All rights reserved.

6 8. 3 Restrictions on Operator Overloading 2003 Prentice Hall, Inc. All rights reserved.

8. 4 Operator Functions As Class Members Vs. Global Functions • Operator functions –

8. 4 Operator Functions As Class Members Vs. Global Functions • Operator functions – Member functions • Use this keyword to implicitly get argument • Gets left operand for binary operators (like +) • Leftmost object must be of same class as operator – Non member functions • Need parameters for both operands • Can have object of different class than operator • Must be a friend to access private or protected data – Operator member functions of a specific class are called • Left operand of binary operator of same class • Single operand of unitary operator of same class 2003 Prentice Hall, Inc. All rights reserved. 7

8. 4 Operator Functions As Class Members Vs. As Friend Functions • Commutative operators

8. 4 Operator Functions As Class Members Vs. As Friend Functions • Commutative operators – May want + to be commutative • So both “a + b” and “b + a” work – Suppose we have two different classes – Overloaded operator can only be member function when its class is on left • Huge. Int. Class + Long int • Can be member function – When other way, need a non-member overload function • Long int + Huge. Int. Class 2003 Prentice Hall, Inc. All rights reserved. 8

8. 5 Overloading Stream-Insertion and Stream-Extraction Operators • << and >> – Already overloaded

8. 5 Overloading Stream-Insertion and Stream-Extraction Operators • << and >> – Already overloaded to process each built-in type – Can also process a user-defined class • Example program – Class Phone. Number • Holds a telephone number – Print out formatted number automatically • (123) 456 -7890 2003 Prentice Hall, Inc. All rights reserved. 9

1 2 3 4 // Fig. 8. 3: fig 08_03. cpp // Overloading the

1 2 3 4 // Fig. 8. 3: fig 08_03. cpp // Overloading the stream-insertion and // stream-extraction operators. #include <iostream> 5 6 7 8 9 10 using using 11 12 #include <iomanip> 13 14 using std: : setw; 15 16 17 18 19 // Phone. Number class definition class Phone. Number { friend ostream &operator<<( ostream&, const Phone. Number & ); friend istream &operator>>( istream&, Phone. Number & ); 20 21 22 23 24 private: char area. Code[ 4 ]; char exchange[ 4 ]; char line[ 5 ]; 25 26 }; // end class Phone. Number std: : cout; std: : cin; std: : endl; std: : ostream; std: : istream; Outline fig 08_03. cpp (1 of 3) // 3 -digit area code and null // 3 -digit exchange and null // 4 -digit line and null 2003 Prentice Hall, Inc. All rights reserved. 10

27 28 29 30 31 32 33 34 35 36 37 38 39 40

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 // overloaded stream-insertion operator; cannot be // a member function if we would like to invoke it with // cout << some. Phone. Number; ostream &operator<<( ostream &output, const Phone. Number &num ) { output << "(" << num. area. Code << ") " << num. exchange << "-" << num. line; return output; Outline fig 08_03. cpp (2 of 3) // enables cout << a << b << c; } // end function operator<< // overloaded stream-extraction operator; cannot be // a member function if we would like to invoke it with // cin >> some. Phone. Number; istream &operator>>( istream &input, Phone. Number &num ) { input. ignore(); // skip ( input >> setw( 4 ) >> num. area. Code; // input area code input. ignore( 2 ); // skip ) and space input >> setw( 4 ) >> num. exchange; // input exchange input. ignore(); // skip dash (-) input >> setw( 5 ) >> num. line; // input line return input; // enables cin >> a >> b >> c; 2003 Prentice Hall, Inc. All rights reserved. 11

53 54 } // end function operator>> 55 56 57 58 int main() {

53 54 } // end function operator>> 55 56 57 58 int main() { Phone. Number phone; // create object phone 59 60 cout << "Enter phone number in the form (123) 456 -7890: n" ; 61 62 63 64 // cin >> phone invokes operator>> by implicitly issuing // the non-member function call operator>>( cin, phone ) cin >> phone; 65 66 cout << "The phone number entered was: " ; 67 68 69 70 // cout << phone invokes operator<< by implicitly issuing // the non-member function call operator<<( cout, phone ) cout << phone << endl; 71 72 return 0; 73 74 Outline fig 08_03. cpp (3 of 3) fig 08_03. cpp output (1 of 1) } // end main Enter phone number in the form (123) 456 -7890: (800) 555 -1212 The phone number entered was: (800) 555 -1212 2003 Prentice Hall, Inc. All rights reserved. 12

13 8. 6 Overloading Unary Operators • Overloading unary operators – Non-static member function,

13 8. 6 Overloading Unary Operators • Overloading unary operators – Non-static member function, no arguments – Non-member function, one argument • Argument must be class object or reference to class object – Remember, static functions only access static data 2003 Prentice Hall, Inc. All rights reserved.

14 8. 6 Overloading Unary Operators • Upcoming example (8. 10) – Overload !

14 8. 6 Overloading Unary Operators • Upcoming example (8. 10) – Overload ! to test for empty string – If non-static member function, needs no arguments • !s becomes s. operator!() class String { public: bool operator!() const; . . . }; – If non-member function, needs one argument • s! becomes operator!(s) class String { friend bool operator!( const String & ). . . } 2003 Prentice Hall, Inc. All rights reserved.

15 8. 7 Overloading Binary Operators • Overloading binary operators – Non-static member function,

15 8. 7 Overloading Binary Operators • Overloading binary operators – Non-static member function, one argument – Non-member function, two arguments • One argument must be class object or reference • Upcoming example – If non-static member function, needs one argument class String { public: const String &operator+=( const String & ); . . . }; – y += z equivalent to y. operator+=( z ) 2003 Prentice Hall, Inc. All rights reserved.

16 8. 7 Overloading Binary Operators • Upcoming example – If non-member function, needs

16 8. 7 Overloading Binary Operators • Upcoming example – If non-member function, needs two arguments – Example: class String { friend const String &operator+=( String &, const String & ); . . . }; – y += z equivalent to operator+=( y, z ) 2003 Prentice Hall, Inc. All rights reserved.

17 8. 8 Converting between Types • Casting – Traditionally, cast integers to floats,

17 8. 8 Converting between Types • Casting – Traditionally, cast integers to floats, etc. – May need to convert between user-defined types • Cast operator (conversion operator) – Convert from • One class to another • Class to built-in type (int, char, etc. ) – Must be non-static member function • Cannot be friend – Do not specify return type • Implicitly returns type to which you are converting 2003 Prentice Hall, Inc. All rights reserved.

18 8. 8 Converting between Types • Example – Prototype A: : operator char

18 8. 8 Converting between Types • Example – Prototype A: : operator char *() const; • Casts class A to a temporary char * • (char *)s calls s. operator char*() – Also • A: : operator int() const; • A: : operator Other. Class() const; 2003 Prentice Hall, Inc. All rights reserved.

19 8. 8 Converting between Types • Casting can prevent need for overloading –

19 8. 8 Converting between Types • Casting can prevent need for overloading – Suppose class String can be cast to char * – cout << s; // s is a String • Compiler implicitly converts s to char * • Do not have to overload << – Compiler can only do 1 cast 2003 Prentice Hall, Inc. All rights reserved.

20 8. 9 Overloading ++ and -- • Increment/decrement operators can be overloaded –

20 8. 9 Overloading ++ and -- • Increment/decrement operators can be overloaded – Add 1 to a Date object, d 1 – Prototype (member function) • Date &operator++(); • ++d 1 same as d 1. operator++() – Prototype (non-member) • Friend Date &operator++( Date &); • ++d 1 same as operator++( d 1 ) 2003 Prentice Hall, Inc. All rights reserved.

21 8. 9 Overloading ++ and -- • To distinguish pre/post increment – Post

21 8. 9 Overloading ++ and -- • To distinguish pre/post increment – Post increment has a dummy parameter • int of 0 – Prototype (member function) • Date operator++( int ); • d 1++ same as d 1. operator++( 0 ) – Prototype (non-member) • friend Date operator++( Data &, int ); • d 1++ same as operator++( d 1, 0 ) – Integer parameter does not have a name • Not even in function definition 2003 Prentice Hall, Inc. All rights reserved.

22 8. 9 Overloading ++ and -- • Return values – Preincrement • Returns

22 8. 9 Overloading ++ and -- • Return values – Preincrement • Returns by reference (Date &) • lvalue (can be assigned) – Postincrement • Returns by value • Returns temporary object with old value • rvalue (cannot be on left side of assignment) • Decrement operator analogous 2003 Prentice Hall, Inc. All rights reserved.

23 8. 10 Case Study: A Date Class • Example Date class – Overloaded

23 8. 10 Case Study: A Date Class • Example Date class – Overloaded increment operator • Change day, month and year – Overloaded += operator – Function to test for leap years – Function to determine if day is last of month 2003 Prentice Hall, Inc. All rights reserved.

1 2 3 4 5 // Fig. 8. 10: date 1. h // Date

1 2 3 4 5 // Fig. 8. 10: date 1. h // Date class definition. #ifndef DATE 1_H #define DATE 1_H #include <iostream> 6 7 using std: : ostream; 8 9 10 class Date { friend ostream &operator<<( ostream &, const Date & ); 11 12 13 14 public: Date( int m = 1, int d = 1, int y = 1900 ); // constructor void set. Date( int, int ); // set the date Outline date 1. h (1 of 2) 15 16 17 Date &operator++(); Date operator++( int ); 18 19 const Date &operator+=( int ); // add days, modify object 20 21 22 bool leap. Year( int ) const; bool end. Of. Month( int ) const; // preincrement operator // postincrement operator // is this a leap year? // is this end of month? 2003 Prentice Hall, Inc. All rights reserved. 24

23 24 25 26 27 28 29 30 Outline private: int month; int day;

23 24 25 26 27 28 29 30 Outline private: int month; int day; int year; static const int days[]; void help. Increment(); 31 32 }; // end class Date 33 34 #endif date 1. h (2 of 2) // array of days per month // utility function 2003 Prentice Hall, Inc. All rights reserved. 25

1 2 3 4 // Fig. 8. 11: date 1. cpp // Date class

1 2 3 4 // Fig. 8. 11: date 1. cpp // Date class member function definitions. #include <iostream> #include "date 1. h" 5 6 7 8 9 // initialize static member at file scope; // one class-wide copy const int Date: : days[] = { 0, 31, 28, 31, 30, 31 }; 10 11 12 13 14 // Date constructor Date: : Date( int m, int d, int y ) { set. Date( m, d, y ); 15 16 } // end Date constructor 17 18 19 20 21 22 // set month, day and year void Date: : set. Date( int mm, int dd, int yy ) { month = ( mm >= 1 && mm <= 12 ) ? mm : 1; year = ( yy >= 1900 && yy <= 2100 ) ? yy : 1900; Outline date 1. cpp (1 of 5) 23 2003 Prentice Hall, Inc. All rights reserved. 26

24 25 26 27 28 29 30 31 32 33 34 35 36 37

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 // test for a if ( month == day = ( dd else day = ( dd leap year 2 && leap. Year( year ) ) >= 1 && dd <= 29 ) ? dd : 1; >= 1 && dd <= days[ month ] ) ? dd : 1; Outline date 1. cpp (2 of 5) } // end function set. Date // overloaded preincrement operator Date &Date: : operator++() { help. Increment(); return *this; // reference return to create an lvalue } // end function operator++ // overloaded postincrement operator; note that the dummy // integer parameter does not have a parameter name Date: : operator++( int ) { Date temp = *this; // hold current state of object help. Increment(); // return unincremented, saved, temporary object return temp; // value return; not a reference return } // end function operator++ 2003 Prentice Hall, Inc. All rights reserved. 27

52 53 54 55 56 57 58 59 // add specified number of days

52 53 54 55 56 57 58 59 // add specified number of days to date const Date &Date: : operator+=( int additional. Days ) { for ( int i = 0; i < additional. Days; i++ ) help. Increment(); return *this; Outline date 1. cpp (3 of 5) // enables cascading 60 61 } // end function operator+= 62 63 64 65 66 67 68 69 70 71 // if the year is a leap year, return true; // otherwise, return false bool Date: : leap. Year( int test. Year ) const { if ( test. Year % 400 == 0 || ( test. Year % 100 != 0 && test. Year % 4 == 0 ) ) return true; // a leap year else return false; // not a leap year 72 73 } // end function leap. Year 74 2003 Prentice Hall, Inc. All rights reserved. 28

75 76 77 78 79 80 81 // determine whether the day is the

75 76 77 78 79 80 81 // determine whether the day is the last day of the month bool Date: : end. Of. Month( int test. Day ) const { if ( month == 2 && leap. Year( year ) ) return test. Day == 29; // last day of Feb. in leap year else return test. Day == days[ month ]; 82 83 } // end function end. Of. Month 84 85 86 87 88 89 90 // function to help increment the date void Date: : help. Increment() { // day is not end of month if ( !end. Of. Month( day ) ) ++day; 91 92 93 94 95 96 97 98 Outline date 1. cpp (4 of 5) else // day is end of month and month < 12 if ( month < 12 ) { ++month; day = 1; } 99 2003 Prentice Hall, Inc. All rights reserved. 29

100 101 102 103 104 105 // last day of year else { ++year;

100 101 102 103 104 105 // last day of year else { ++year; month = 1; day = 1; } Outline date 1. cpp (5 of 5) 106 107 } // end function help. Increment 108 109 // overloaded output operator 110 ostream &operator<<( ostream &output, const Date &d ) 111 { 112 static char *month. Name[ 13 ] = { "", "January", 113 "February", "March", "April", "May", "June", 114 "July", "August", "September", "October", 115 "November", "December" }; 116 117 118 output << month. Name[ d. month ] << ' ' << d. day << ", " << d. year; 119 120 return output; // enables cascading 121 122 } // end function operator<< 2003 Prentice Hall, Inc. All rights reserved. 30

1 2 3 // Fig. 8. 12: fig 08_12. cpp // Date class test

1 2 3 // Fig. 8. 12: fig 08_12. cpp // Date class test program. #include <iostream> 4 5 6 using std: : cout; using std: : endl; 7 8 #include "date 1. h" 9 10 11 12 13 14 int main() { Date d 1; // defaults to January 1, 1900 Date d 2( 12, 27, 1992 ); Date d 3( 0, 99, 8045 ); // invalid date Outline fig 08_12. cpp (1 of 2) // Date class definition 15 16 17 cout << "d 1 is " << d 1 << "nd 2 is " << d 2 << "nd 3 is " << d 3; 18 19 cout << "nnd 2 += 7 is " << ( d 2 += 7 ); 20 21 22 23 d 3. set. Date( 2, 28, 1992 ); cout << "nn d 3 is " << d 3; cout << "n++d 3 is " << ++d 3; 24 25 Date d 4( 7, 13, 2002 ); 2003 Prentice Hall, Inc. All rights reserved. 31

26 27 28 29 30 cout << << cout << "nn. Testing the preincrement

26 27 28 29 30 cout << << cout << "nn. Testing the preincrement operator: n" " d 4 is " << d 4 << 'n'; "++d 4 is " << ++d 4 << 'n'; " d 4 is " << d 4; 31 32 33 34 35 cout << << cout << "nn. Testing the postincrement operator: n" " d 4 is " << d 4 << 'n'; "d 4++ is " << d 4++ << 'n'; " d 4 is " << d 4 << endl; 36 37 return 0; 38 39 Outline fig 08_12. cpp (2 of 2) } // end main 2003 Prentice Hall, Inc. All rights reserved. 32

d 1 is January 1, 1900 d 2 is December 27, 1992 d 3

d 1 is January 1, 1900 d 2 is December 27, 1992 d 3 is January 1, 1900 d 2 += 7 is January 3, 1993 Outline fig 08_12. cpp output (1 of 1) d 3 is February 28, 1992 ++d 3 is February 29, 1992 Testing d 4 is ++d 4 is the preincrement operator: July 13, 2002 July 14, 2002 Testing d 4 is d 4++ is d 4 is the postincrement operator: July 14, 2002 July 15, 2002 2003 Prentice Hall, Inc. All rights reserved. 33