22
More on Operator Overloading CS-2303, C-Term 20 10 1 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The C Programming Language, 2 nd edition, by Kernighan and Ritchie, from C: How to Program, 5 th and 6 th editions, by Deitel and Deitel, and from The C++ Programming Language, 3 rd edition, by Bjarne Stroustrup)

More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

  • View
    217

  • Download
    1

Embed Size (px)

Citation preview

Page 1: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 1

More on Operator Overloading

CS-2303System Programming Concepts

(Slides include materials from The C Programming Language, 2nd edition, by Kernighan and Ritchie, from C: How to Program, 5th and 6th editions, by Deitel and Deitel, and from

The C++ Programming Language, 3rd edition, by Bjarne Stroustrup)

Page 2: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 2

Case Study — Array Class

• Problems with pointer-based arrays in C++:–– No range checking.

– Cannot be compared meaningfully with ==

– No array assignment (array names are const pointers).

– If array passed to a function, size must be passed as a separate argument.

• Can we do better?– I.e., can we create a data type that looks like an array

but has the missing properties

Page 3: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 3

Point of Operator Overloading

• By using C++ classes and operator overloading, …

• … one can significantly change the capabilities of a built-in type

• In this case, of the built-in array type

Page 4: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 4

Case Study — Array Class

• Implement an Array class with:–– Range checking– Array assignment ( = )– Arrays that know their own size.– Array comparisons with == and !=– Output/input of entire arrays with << and >>

Deitel & Deitel, §22.8

Page 5: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 5

Array Class Copy Constructor

• Used whenever copy of object is needed:– Passing by value (return value or parameter).– Initializing an object with a copy of another of

same type.

Array newArray( oldArray ); or

Array newArray = oldArray;– Both are identical– newArray is a copy of oldArray.

Page 6: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 6

Definition – Copy Constructor

• A constructor of some type T of the form

T (const & T);

• The single argument must be a const reference to an existing object of same type

• Creates a duplicate of the existing object• Used whenever a copy of an object is needed• Including arguments to functions, results returned

from functions

Copy constructors always

take

reference argument!

Reason: avoid infinite recursion!

Page 7: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 7

1 // Fig. 22.6: Array.h

2 // Array class for storing arrays of integers.

3 #ifndef ARRAY_H

4 #define ARRAY_H

5

6 #include <iostream>

7 using std::ostream;

8 using std::istream;

9

10 class Array

11 {

12 friend ostream &operator<<( ostream &, const Array & );

13 friend istream &operator>>( istream &, Array & );

14 public:

15 Array( int = 10 ); // default constructor

16 Array( const Array & ); // copy constructor

17 ~Array(); // destructor

18 int getSize() const; // return size

19

20 const Array &operator=( const Array & ); // assignment operator

21 bool operator==( const Array & ) const; // equality operator

22

23 // inequality operator; returns opposite of == operator

24 bool operator!=( const Array &right ) const

25 {

26 return ! ( *this == right ); // invokes Array::operator==

27 } // end function operator!=

Most operators overloaded as member functions (except << and >>

which must be global functions)

Prototype for copy constructor

!= operator simply returns opposite of == operator – only need to define the == operator

Array Class Definition

Page 8: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 8

1 // Fig. 22.6: Array.h

2 // Array class for storing arrays of integers.

3 #ifndef ARRAY_H

4 #define ARRAY_H

5

6 #include <iostream>

7 using std::ostream;

8 using std::istream;

9

10 class Array

11 {

12 friend ostream &operator<<( ostream &, const Array & );

13 friend istream &operator>>( istream &, Array & );

14 public:

15 Array( int = 10 ); // default constructor

16 Array( const Array & ); // copy constructor

17 ~Array(); // destructor

18 int getSize() const; // return size

19

20 const Array &operator=( const Array & ); // assignment operator

21 bool operator==( const Array & ) const; // equality operator

22

23 // inequality operator; returns opposite of == operator

24 bool operator!=( const Array &right ) const

25 {

26 return ! ( *this == right ); // invokes Array::operator==

27 } // end function operator!=

Array Class Definition

Note weird return type:–constant reference

Not explained in D&D

Page 9: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 9

28

29 // subscript operator for non-const objects returns modifiable lvalue

30 int &operator[]( int );

31

32 // subscript operator for const objects returns rvalue

33 int operator[]( int ) const;

34 private:

35 int size; // pointer-based array size

36 int *ptr; // pointer to first element of pointer-based array

37 }; // end class Array

38

39 #endif

Operators for accessing specific elements of Array object

Note: An example of pointer data Note: An example of pointer data membermember

Array Class Definition (continued)

Page 10: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 10

1 // Fig 22.7: Array.cpp

2 // Member-function definitions for class Array

3 #include <iostream>

4 using std::cerr;

5 using std::cout;

6 using std::cin;

7 using std::endl;

8

9 #include <iomanip>

10 using std::setw;

11

12 #include <cstdlib> // exit function prototype

13 using std::exit;

14

15 #include "Array.h" // Array class definition

16

17 // default constructor for class Array (default size 10)

18 Array::Array( int arraySize )

19 {

20 size = ( arraySize > 0 ? arraySize : 10 ); // validate arraySize

21 ptr = new int[ size ]; // create space for pointer-based array

22

23 for ( int i = 0; i < size; i++ )

24 ptr[ i ] = 0; // set pointer-based array element

25 } // end Array default constructor

Array Class Implementation

Page 11: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 11

26

27 // copy constructor for class Array;

28 // must receive a reference to prevent infinite recursion

29 Array::Array( const Array &arrayToCopy )

30 : size( arrayToCopy.size )

31 {

32 ptr = new int[ size ]; // create space for pointer-based array

33

34 for ( int i = 0; i < size; i++ )

35 ptr[ i ] = arrayToCopy.ptr[ i ]; // copy into object

36 } // end Array copy constructor

37

38 // destructor for class Array

39 Array::~Array()

40 {

41 delete [] ptr; // release pointer-based array space

42 } // end destructor

43

44 // return number of elements of Array

45 int Array::getSize() const

46 {

47 return size; // number of elements in Array

48 } // end function getSize

We must declare a new integer array so the objects do not point to the same memory

Array Class Implementation (continued)

Page 12: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 12

49

50 // overloaded assignment operator;

51 // const return avoids: ( a1 = a2 ) = a3

52 const Array &Array::operator=( const Array &right )

53 {

54 if ( &right != this ) // avoid self-assignment

55 {

56 // for Arrays of different sizes, deallocate original

57 // left-side array, then allocate new left-side array

58 if ( size != right.size )

59 {

60 delete [] ptr; // release space

61 size = right.size; // resize this object

62 ptr = new int[ size ]; // create space for array copy

63 } // end inner if

64

65 for ( int i = 0; i < size; i++ )

66 ptr[ i ] = right.ptr[ i ]; // copy array into object

67 } // end outer if

68

69 return *this; // enables x = y = z, for example

70 } // end function operator=

Want to avoid self assignment

This would be dangerous if this is the same Array as right

Array Class Implementation (continued)Note that Copy Constructor andassignment are not the same thing.(But they are similar!)

Page 13: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 13

71

72 // determine if two Arrays are equal and

73 // return true, otherwise return false

74 bool Array::operator==( const Array &right ) const

75 {

76 if ( size != right.size )

77 return false; // arrays of different number of elements

78

79 for ( int i = 0; i < size; i++ )

80 if ( ptr[ i ] != right.ptr[ i ] )

81 return false; // Array contents are not equal

82

83 return true; // Arrays are equal

84 } // end function operator==

85

86 // overloaded subscript operator for non-const Arrays;

87 // reference return creates a modifiable lvalue

88 int &Array::operator[]( int subscript )

89 {

90 // check for subscript out-of-range error

91 if ( subscript < 0 || subscript >= size )

92 {

93 cerr << "\nError: Subscript " << subscript

94 << " out of range" << endl;

95 exit( 1 ); // terminate program; subscript out of range

96 } // end if

97

98 return ptr[ subscript ]; // reference return

99 } // end function operator[]

integers1[ 5 ] calls integers1.operator[]( 5 )

Array Class Implementation (continued)

Page 14: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 14

100

101 // overloaded subscript operator for const Arrays

102 // const reference return creates an rvalue

103 int Array::operator[]( int subscript ) const

104 {

105 // check for subscript out-of-range error

106 if ( subscript < 0 || subscript >= size )

107 {

108 cerr << "\nError: Subscript " << subscript

109 << " out of range" << endl;

110 exit( 1 ); // terminate program; subscript out of range

111 } // end if

112

113 return ptr[ subscript ]; // returns copy of this element

114 } // end function operator[]

115

116 // overloaded input operator for class Array;

117 // inputs values for entire Array

118 istream &operator>>( istream &input, Array &a )

119 {

120 for ( int i = 0; i < a.size; i++ )

121 input >> a.ptr[ i ];

122

123 return input; // enables cin >> x >> y;

124 } // end function

Array Class Implementation (continued)

Should be some errorchecking here

Notice the return type

Page 15: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 15

125

126 // overloaded output operator for class Array

127 ostream &operator<<( ostream &output, const Array &a )

128 {

129 int i;

130

131 // output private ptr-based array

132 for ( i = 0; i < a.size; i++ )

133 {

134 output << setw( 12 ) << a.ptr[ i ];

135

136 if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output

137 output << endl;

138 } // end for

139

140 if ( i % 4 != 0 ) // end last line of output

141 output << endl;

142

143 return output; // enables cout << x << y;

144 } // end function operator<<

Array Class Implementation (continued)

Notice the return type

Page 16: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 16

1 // Fig. 22.8: fig22_08.cpp

2 // Array class test program.

3 #include <iostream>

4 using std::cout;

5 using std::cin;

6 using std::endl;

7

8 #include "Array.h"

9

10 int main()

11 {

12 Array integers1( 7 ); // seven-element Array

13 Array integers2; // 10-element Array by default

14

15 // print integers1 size and contents

16 cout << "Size of Array integers1 is "

17 << integers1.getSize()

18 << "\nArray after initialization:\n" << integers1;

19

20 // print integers2 size and contents

21 cout << "\nSize of Array integers2 is "

22 << integers2.getSize()

23 << "\nArray after initialization:\n" << integers2;

24

25 // input and print integers1 and integers2

26 cout << "\nEnter 17 integers:" << endl;

27 cin >> integers1 >> integers2;

Retrieve number of elements in Array

Use overloaded >> operator to input

Array Class Usage

Page 17: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 17

28

29 cout << "\nAfter input, the Arrays contain:\n"

30 << "integers1:\n" << integers1

31 << "integers2:\n" << integers2;

32

33 // use overloaded inequality (!=) operator

34 cout << "\nEvaluating: integers1 != integers2" << endl;

35

36 if ( integers1 != integers2 )

37 cout << "integers1 and integers2 are not equal" << endl;

38

39 // create Array integers3 using integers1 as an

40 // initializer; print size and contents

41 Array integers3( integers1 ); // invokes copy constructor

42

43 cout << "\nSize of Array integers3 is "

44 << integers3.getSize()

45 << "\nArray after initialization:\n" << integers3;

46

47 // use overloaded assignment (=) operator

48 cout << "\nAssigning integers2 to integers1:" << endl;

49 integers1 = integers2; // note target Array is smaller

50

51 cout << "integers1:\n" << integers1

52 << "integers2:\n" << integers2;

53

54 // use overloaded equality (==) operator

55 cout << "\nEvaluating: integers1 == integers2" << endl;

Use overloaded << operator to output

Use overloaded != operator

to test for inequality

Use copy constructor

Use overloaded = operator to assign

Array Class Usage (continued)

Page 18: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 18

56

57 if ( integers1 == integers2 )

58 cout << "integers1 and integers2 are equal" << endl;

59

60 // use overloaded subscript operator to create rvalue

61 cout << "\nintegers1[5] is " << integers1[ 5 ];

62

63 // use overloaded subscript operator to create lvalue

64 cout << "\n\nAssigning 1000 to integers1[5]" << endl;

65 integers1[ 5 ] = 1000;

66 cout << "integers1:\n" << integers1;

67

68 // attempt to use out-of-range subscript

69 cout << "\nAttempt to assign 1000 to integers1[15]" << endl;

70 integers1[ 15 ] = 1000; // ERROR: out of range

71 return 0;

72 } // end main

Use overloaded == operator to test for equality

Use overloaded [] operator to access individual integers, with range-checking

Array Class Usage (continued)

Page 19: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 19

Questions?

Page 20: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 20

Note about Type Conversion

• Any single-argument constructor can be used as a type-conversion between the argument type and the object type

• May be invoked implicitly or explicitly• Explict:– let a and b be complex

a = b + complex(2.0)

• Implicit:– whenever compiler figures out it needs one type but has anothera = b + 2.0 /* NO overloaded ‘+’ operator for complex, real */

Page 21: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 21

Forcing explicit Type Conversion

• Sometimes, you don’t want compiler to make an implicit conversion

• Prefix constructor by explicit in type definition– Example:– (line 15 of Array class definition)

explicit Array(int =10);

– Suppresses use of this constructor for an implicit type conversion.

Page 22: More on Operator Overloading CS-2303, C-Term 20101 More on Operator Overloading CS-2303 System Programming Concepts (Slides include materials from The

More on Operator Overloading

CS-2303, C-Term 2010 22

Questions?