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. as friend Functions 8.5 Overloading Stream-Insertion and Stream-Extraction Operators 8.6 Overloading Unary Operators 8.7 Overloading Binary Operators 8.8 Case Study: Array Class 8.9 Converting between Types 8.10 Case Study: A String Class 8.11 Overloading ++ and -8.12 Case Study: A Date Class 8.13 Standard Library Classes string and vector 2003 Prentice Hall, Inc. All rights reserved. 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

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. 5 8.3 Restrictions on Operator Overloading Operators that can be overloaded + - * / % ^ & | ~ ! =

< > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= && || ++ --

->* , -> [] () new delete new[] delete[] Operators that cannot be overloaded . .* 2003 Prentice Hall, Inc. All rights reserved. :: ?: sizeof 6 // Specification file for the FeetInches class #ifndef FEETINCHES_H #define FEETINCHES_H Outline Gaddis (1 of 3) // The FeetInches class holds distances or measurements // expressed in feet and inches.

class FeetInches { private: int feet; int inches; void simplify(); // Defined in feetinch.cpp public: FeetInches(int f = 0, int i = 0) { feet = f; inches = i; simplify(); } 2003 Prentice Hall, Inc. All rights reserved. 7 void setFeet(int f) { feet = f; } void setInches(int i) { inches = i; simplify(); } Outline Gaddis (1 of 3) int getFeet() { return feet; } int getInches() { return inches; } FeetInches operator + (const FeetInches &); //Overloaded + FeetInches operator - (const FeetInches &); //Overloaded }; #endif 2003 Prentice Hall, Inc. All rights reserved. 8 // Implementation file for the FeetInches class Outline #include // Needed for abs() #include "FeetInches2.h" Gaddis (1 of 3)

//************************************************************ // Definition of member function simplify. This function * // checks for values in the inches member greater than * // twelve or less than zero. If such a value is found, * // the numbers in feet and inches are adjusted to conform * // to a standard feet & inches expression. * //************************************************************ void FeetInches::simplify() { if (inches >= 12) {feet += (inches / 12); inches = inches % 12;} else if (inches < 0) {feet -= ((abs(inches) / 12) + 1); inches = 12 - (abs(inches) % 12);} } 2003 Prentice Hall, Inc. All rights reserved. 9 Outline //********************************************** // Overloaded binary + operator. * //********************************************** Gaddis (1 of 3) FeetInches FeetInches::operator + (const FeetInches &right) { FeetInches temp; temp.inches = inches + right.inches; temp.feet = feet + right.feet; temp.simplify(); return temp; }

2003 Prentice Hall, Inc. All rights reserved. 10 //********************************************** // Overloaded binary - operator. * //********************************************** Outline Gaddis (1 of 3) FeetInches FeetInches::operator - (const FeetInches &right) { FeetInches temp; temp.inches = inches - right.inches; temp.feet = feet - right.feet; temp.simplify(); return temp; } 2003 Prentice Hall, Inc. All rights reserved. 11 // This program demonstrates the FeetInches class's overloaded Outline // + and - operators. #include Gaddis (1 of 3) #include "FeetInches2.h" using namespace std; int main() { FeetInches first, second, third; // 3 FeetInches objects int f, i; // To hold user input // Get a distance from the user. cout << "Enter a distance in feet and inches: ";

cin >> f >> i; // Store the distance in the first object. first.setFeet(f); first.setInches(i); 2003 Prentice Hall, Inc. All rights reserved. 12 // Get another distance from the user. Outline cout << "Enter another distance in feet and inches: "; cin >> f >> i; Gaddis (1 of 3) // Store the distance in second. second.setFeet(f); second.setInches(i); // Assign first + second to third. third = first + second; // Display the result. cout << "first + second = "; cout << third.getFeet() << " feet, "; cout << third.getInches() << " inches.\n"; // Assign first - second to third. third = first - second; 2003 Prentice Hall, Inc. All rights reserved. 13 // Display the cout << cout << cout << result. "first - second = "; third.getFeet() << " feet, "; third.getInches() << " inches.\n"; Outline Gaddis

(1 of 3) return 0; } Enter Enter first first a distance in feet and inches: 6 5 another distance in feet and inches: 3 10 + second = 10 feet, 3 inches second = 2 feet, 7 inches We have replaced something that would have looked something like: FeetInches::addFeetInches(FeetInches &third, FeetInches first, FeetInches second); with third = first + second; 2003 Prentice Hall, Inc. All rights reserved. 14 8.4 Operator Functions As Class Members Vs. As Friend 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 Called when Left operand of binary operator of same class Single operand of unitary operator of same class 2003 Prentice Hall, Inc. All rights reserved.

15 8.4 Operator Functions As Class Members Vs. As Friend Functions Overloaded << operator Left operand of type ostream & Such as cout object in cout << classObject Similarly, overloaded >> needs istream & Thus, both must be non-member functions 2003 Prentice Hall, Inc. All rights reserved. 16 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 HugeIntClass + Long int Can be member function When other way, need a non-member overload function Long int + HugeIntClass 2003 Prentice Hall, Inc. All rights reserved. 17 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 PhoneNumber Holds a telephone number

Print out formatted number automatically (123) 456-7890 2003 Prentice Hall, Inc. All rights reserved. 18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // Fig. 8.3: fig08_03.cpp // Overloading the stream-insertion and // stream-extraction operators. #include using using using using using

Outline fig08_03.cpp (1 of 3) std::cout; std::cin; std::endl; std::ostream; std::istream; #include Notice function prototypes for overloaded operators >> and << using std::setw; // PhoneNumber class definitionThey must be non-member friend class PhoneNumber { functions, since the object of class friend ostream &operator<<( ostream&, const PhoneNumber & ); Phonenumber appears on the right friend istream &operator>>( istream&, PhoneNumber & ); of the operator. private: char areaCode[ 4 ]; char exchange[ 4 ]; char line[ 5 ]; cin << object // 3-digit and null coutarea >> code object // 3-digit exchange and null // 4-digit line and null }; // end class PhoneNumber

2003 Prentice Hall, Inc. All rights reserved. 19 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 Outline // overloaded stream-insertion operator; cannot be // a member function if we would like to invoke it with // cout << somePhoneNumber; fig08_03.cpp ostream &operator<<( ostream &output, const PhoneNumber &num ) (2 of 3) { The expression: output << "(" << num.areaCode << ") "

cout << phone; << num.exchange << "-" << num.line; return output; // enables cout << a << b << c; } // end function operator<< is interpreted as the function call: operator<<(cout, phone); output is an alias for cout. // overloaded stream-extraction operator; cannot beThis allows objects to be cascaded. // a member function if we would like to invoke it cout with << phone1 << phone2; ignore() skips specified // cin >> somePhoneNumber; number of characters fromfirst calls istream &operator>>( istream &input, PhoneNumber &num ) operator<<(cout, phone1), and input (1 by default). { returns cout. input.ignore(); // skip ( input >> setw( 4 ) >> num.areaCode; // input area code Next, cout << phone2 executes. input.ignore( 2 ); // skip ) and space manipulator input >> setw( 4 ) >> num.exchange;Stream // input exchangesetw input.ignore(); // skipnumber dash (-) restricts of characters input >> setw( 5 ) >> num.line; // input line allows 3 read.

setw(4) return input; // enables cin characters to be read, leaving >> a >> >> null c; character. room forb the 2003 Prentice Hall, Inc. All rights reserved. 20 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 } // end function operator>> int main() { PhoneNumber phone; // create object phone

cout << "Enter phone number in the form (123) 456-7890:\n"; Outline fig08_03.cpp (3 of 3) fig08_03.cpp output (1 of 1) // cin >> phone invokes operator>> by implicitly issuing // the non-member function call operator>>( cin, phone ) cin >> phone; cout << "The phone number entered was: " ; // cout << phone invokes operator<< by implicitly issuing // the non-member function call operator<<( cout, phone ) cout << phone << endl; return 0; } // 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. 21 22 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. 23 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. 24 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. 25 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. 26 8.8 Case Study: Array class Arrays in C++ No range checking Cannot be compared meaningfully with == No array assignment (array names const pointers) Cannot input/output entire arrays at once One element at a time Example:Implement an Array class with Range checking Array assignment Arrays that know their size Outputting/inputting entire arrays with << and >> Array comparisons with == and != 2003 Prentice Hall, Inc. All rights reserved. 27 8.8 Case Study: Array class Copy constructor Used whenever copy of object needed Passing by value (return value or parameter)

Initializing an object with a copy of another Array newArray( oldArray ); newArray copy of oldArray Prototype for class Array Array( const Array & ); Must take reference Otherwise, pass by value Tries to make copy by calling copy constructor Infinite loop 2003 Prentice Hall, Inc. All rights reserved. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // Fig. 8.4: array1.h // Array class for storing arrays of integers. #ifndef ARRAY1_H #define ARRAY1_H

Outline array1.h (1 of 2) #include using std::ostream; using std::istream; class Array { friend ostream &operator<<( ostream &, const Array & ); friend istream &operator>>( istream &, Array & ); public: Array( int = 10 ); Array( const Array & ); ~Array(); int getSize() const; Most operators overloaded as member functions (except << default constructor and >>, which must be noncopy constructor destructor member functions). // // // // return size Prototype for copy constructor. // assignment operator const Array &operator=( const Array & ); // equality operator bool operator==( const Array & ) const; 2003 Prentice Hall, Inc. All rights reserved. 28 27 28 29 30 31 32

33 34 35 36 37 38 39 40 41 42 43 44 45 46 // inequality operator; returns opposite of == operator bool operator!=( const Array &right ) const { return ! ( *this == right ); // invokes Array::operator== Outline array1.h (2 of 2) } // end function operator!= // subscript operator for int &operator[]( int ); != operator simply returns opposite of == operator. non-const objects returns lvalue Thus, only need to define the == operator. // subscript operator for const objects returns rvalue const int &operator[]( int ) const; private: int size; // array size int *ptr; // pointer to first element of array }; // end class Array #endif 2003 Prentice Hall, Inc. All rights reserved.

29 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // Fig 8.5: array1.cpp // Member function definitions for class Array #include Outline array1.cpp (1 of 7) using std::cout; using std::cin; using std::endl; #include using std::setw; #include // C++ standard "new" operator

#include // exit function prototype #include "array1.h" // Array class definition // default constructor for class Array (default size 10) Array::Array( int arraySize ) { // validate arraySize size = ( arraySize > 0 ? arraySize : 10 ); ptr = new int[ size ]; // create space for array 2003 Prentice Hall, Inc. All rights reserved. 30 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

50 for ( int i = 0; i < size; i++ ) ptr[ i ] = 0; // initialize array Outline } // end Array default constructor array1.cpp (2 of 7) // copy constructor for class Array; // must receive a reference to prevent infinite recursion We must declare a new integer array Array::Array( const Array &arrayToCopy ) the objects do not point to the same : size( arrayToCopy.size ) memory. { ptr = new int[ size ]; // create space for array for ( int i = 0; i < size; i++ ) ptr[ i ] = arrayToCopy.ptr[ i ]; so // copy into object } // end Array copy constructor // destructor for class Array Array::~Array() { delete [] ptr; // reclaim array space } // end destructor 2003 Prentice Hall, Inc. All rights reserved. 31 51 52 53 54

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 // return size of array int Array::getSize() const { return size; Outline array1.cpp (3 of 7) } // end function getSize // overloaded assignment operator;Want to avoid self-assignment. // const return avoids: ( a1 = a2 ) = a3 const Array &Array::operator=( const Array &right ) { if ( &right != this ) { // check for self-assignment // for arrays of different sizes, deallocate original // left-side array, then allocate new left-side array if ( size != right.size ) { delete [] ptr; // reclaim space size = right.size; // resize this object

ptr = new int[ size ]; // create space for array copy } // end inner if for ( int i = 0; i < size; i++ ) ptr[ i ] = right.ptr[ i ]; // copy array into object } // end outer if 2003 Prentice Hall, Inc. All rights reserved. 32 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 return *this; // enables x = y = z, for example } // end function operator= Outline array1.cpp (4 of 7) // determine if two arrays are equal and // return true, otherwise return false

bool Array::operator==( const Array &right ) const { if ( size != right.size ) return false; // arrays of different sizes for ( int i = 0; i < size; i++ ) if ( ptr[ i ] != right.ptr[ i ] ) return false; // arrays are not equal return true; // arrays are equal } // end function operator== 2003 Prentice Hall, Inc. All rights reserved. 33 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 // overloaded subscript operator for non-const Arrays // reference return creates an lvalue int &Array::operator[]( int subscript ) { // check for subscript out of range error calls if ( subscript < 0 || subscript >= size integers1[5]

) { integers1.operator[]( cout << "\nError: Subscript " << subscript << " out of range" << endl; exit( 1 ); Outline array1.cpp (5 of 7) 5 ) // terminate program; subscript out of range } // end if exit() (header ) ends the program. return ptr[ subscript ]; // reference return } // end function operator[] 2003 Prentice Hall, Inc. All rights reserved. 34 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

134 135 136 137 138 139 140 141 // overloaded subscript operator for const Arrays // const reference return creates an rvalue const int &Array::operator[]( int subscript ) const { // check for subscript out of range error if ( subscript < 0 || subscript >= size ) { cout << "\nError: Subscript " << subscript << " out of range" << endl; exit( 1 ); Outline array1.cpp (6 of 7) // terminate program; subscript out of range } // end if return ptr[ subscript ]; // const reference return } // end function operator[] // overloaded input operator for class Array; // inputs values for entire array istream &operator>>( istream &input, Array &a ) { for ( int i = 0; i < a.size; i++ ) input >> a.ptr[ i ]; return input; // enables cin >> x >> y; } // end function 2003 Prentice Hall, Inc. All rights reserved. 35

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 // overloaded output operator for class Array ostream &operator<<( ostream &output, const Array &a ) { int i; Outline array1.cpp (7 of 7) // output private ptr-based array for ( i = 0; i < a.size; i++ ) { output << setw( 12 ) << a.ptr[ i ]; if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output output << endl; } // end for if ( i % 4 != 0 ) // end last line of output output << endl; return output; // enables cout << x << y; } // end function operator<<

2003 Prentice Hall, Inc. All rights reserved. 36 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // Fig. 8.6: fig08_06.cpp // Array class test program. #include Outline fig08_06.cpp (1 of 3) using std::cout; using std::cin; using std::endl; #include "array1.h" int main()

{ Array integers1( 7 ); Array integers2; // seven-element Array // 10-element Array by default // print integers1 size and contents cout << "Size of array integers1 is " << integers1.getSize() << "\nArray after initialization:\n" << integers1; // print integers2 size and contents cout << "\nSize of array integers2 is " << integers2.getSize() << "\nArray after initialization:\n" << integers2; 2003 Prentice Hall, Inc. All rights reserved. 37 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

// input and print integers1 and integers2 cout << "\nInput 17 integers:\n"; cin >> integers1 >> integers2; cout << "\nAfter input, the arrays contain:\n" << "integers1:\n" << integers1 << "integers2:\n" << integers2; Outline fig08_06.cpp (2 of 3) // use overloaded inequality (!=) operator cout << "\nEvaluating: integers1 != integers2\n"; if ( integers1 != integers2 ) cout << "integers1 and integers2 are not equal\n"; // create array integers3 using integers1 as an // initializer; print size and contents Array integers3( integers1 ); // calls copy constructor cout << "\nSize of array integers3 is " << integers3.getSize() << "\nArray after initialization:\n" << integers3; 2003 Prentice Hall, Inc. All rights reserved. 38 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

65 66 67 68 69 70 71 72 73 74 75 // use overloaded assignment (=) operator cout << "\nAssigning integers2 to integers1:\n"; integers1 = integers2; // note target is smaller cout << "integers1:\n" << integers1 << "integers2:\n" << integers2; Outline fig08_06.cpp (3 of 3) // use overloaded equality (==) operator cout << "\nEvaluating: integers1 == integers2\n"; if ( integers1 == integers2 ) cout << "integers1 and integers2 are equal\n"; // use overloaded subscript operator to create rvalue cout << "\nintegers1[5] is " << integers1[ 5 ]; // use overloaded subscript operator to create lvalue cout << "\n\nAssigning 1000 to integers1[5]\n"; integers1[ 5 ] = 1000; cout << "integers1:\n" << integers1; // attempt to use out-of-range subscript cout << "\nAttempt to assign 1000 to integers1[15]" << endl; integers1[ 15 ] = 1000; // ERROR: out of range return 0; } // end main 2003 Prentice Hall, Inc. All rights reserved. 39 Size of array integers1 is 7

Array after initialization: 0 0 0 0 Size of array integers2 is 10 Array after initialization: 0 0 0 0 0 0 Outline 0 0 0 0 0 0 0 fig08_06.cpp output (1 of 3) Input 17 integers: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 After input, the arrays contain: integers1: 1 2 5 6 integers2: 8 9 12 13 3

7 4 10 14 11 15 2003 Prentice Hall, Inc. All rights reserved. 40 Evaluating: integers1 != integers2 integers1 and integers2 are not equal Size of array integers3 is 7 Array after initialization: 1 2 5 6 Assigning integers2 to integers1: integers1: 8 9 12 13 16 17 integers2: 8 9 12 13 16 17 Outline 3 7

4 10 14 11 15 10 14 11 15 fig08_06.cpp output (2 of 3) Evaluating: integers1 == integers2 integers1 and integers2 are equal integers1[5] is 13 2003 Prentice Hall, Inc. All rights reserved. 41 Assigning 1000 to integers1[5] integers1: 8 9 12 1000 16 17 Outline 10 14 11 15 fig08_06.cpp output (3 of 3)

Attempt to assign 1000 to integers1[15] Error: Subscript 15 out of range 2003 Prentice Hall, Inc. All rights reserved. 42 43 8.9 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. 44 8.9 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 OtherClass() const; 2003 Prentice Hall, Inc. All rights reserved.

45 8.9 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. 46 8.10 Case Study: A String Class Build class String String creation, manipulation Class string in standard library (more Chapter 15) Conversion constructor Single-argument constructor Turns objects of other types into class objects String s1(hi); Creates a String from a char * Any single-argument constructor is a conversion constructor 2003 Prentice Hall, Inc. All rights reserved. 1 2 3 4 5 6 7 8 9 10 11 12 13 14

15 16 17 18 19 20 21 22 23 24 25 26 // Fig. 8.7: string1.h // String class definition. #ifndef STRING1_H #define STRING1_H Outline string1.h (1 of 3) #include using std::ostream; using std::istream; class String { friend ostream &operator<<( ostream &, const String & ); Conversion constructor friend istream &operator>>( istream &, String & ); to make a String from a char *. public: String( const char * = "" ); // conversion/default ctor String( const String & ); // copy constructor s1 += s2 ~String(); // destructor interpreted as s1.operator+=(s2)

const String &operator=( const String & ); // assignment also concatenate const String &operator+=( const String & ); //Can concatenation bool operator!() const; // bool operator==( const String & ) const; // bool operator<( const String & ) const; // a String and a char * because the iscompiler String will empty? cast the char * test s1 == to s2a String. argument test s1 < s2 However, it can only do 1 level of casting. 2003 Prentice Hall, Inc. All rights reserved. 47 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 53 // test s1 != s2 bool operator!=( const String & right ) const { return !( *this == right ); Outline string1.h (2 of 3) } // end function operator!= // test s1 > s2 bool operator>( const String &right ) const { return right < *this; } // end function operator> // test s1 <= s2 bool operator<=( const String &right ) const { return !( right < *this ); } // end function operator <= // test s1 >= s2 bool operator>=( const String &right ) const { return !( *this < right ); } // end function operator>= 2003 Prentice Hall, Inc. All rights reserved. 48 54

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 char &operator[]( int ); // const char &operator[]( int ) const; // String operator()( int, int ); int getLength() const; private: int length; char *sPtr; Two overloaded subscript subscript operator operators, for const and subscript operator non-const objects. // return a substring Outline string1.h (3 of 3) // return stringcall length Overload the function operator () to return a substring. This operator can

have any amount of operands. // string length // pointer to start of string void setString( const char * ); // utility function }; // end class String #endif 2003 Prentice Hall, Inc. All rights reserved. 49 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

// Fig. 8.8: string1.cpp // Member function definitions for class String. #include Outline string1.cpp (1 of 8) using std::cout; using std::endl; #include using std::setw; #include // C++ standard "new" operator #include #include // strcpy and strcat prototypes // exit prototype #include "string1.h" // String class definition // conversion constructor converts char * to String String::String( const char *s ) : length( strlen( s ) ) { cout << "Conversion constructor: " << s << '\n'; setString( s ); // call utility function } // end String conversion constructor 2003 Prentice Hall, Inc. All rights reserved. 50 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 53 54 // copy constructor String::String( const String © ) : length( copy.length ) { cout << "Copy constructor: " << copy.sPtr << '\n'; setString( copy.sPtr ); // call utility function Outline string1.cpp (2 of 8) } // end String copy constructor // destructor String::~String() { cout << "Destructor: " << sPtr << '\n'; delete [] sPtr; // reclaim string } // end ~String destructor // overloaded = operator; avoids self assignment const String &String::operator=( const String &right )

{ cout << "operator= called\n"; if ( &right != this ) { delete [] sPtr; length = right.length; setString( right.sPtr ); } // // // // avoid self assignment prevents memory leak new String length call utility function 2003 Prentice Hall, Inc. All rights reserved. 51 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

76 77 78 79 80 else cout << "Attempted assignment of a String to itself\n"; return *this; // enables cascaded assignments Outline string1.cpp (3 of 8) } // end function operator= // concatenate right operand to this object and // store in this object. const String &String::operator+=( const String &right ) { size_t newLength = length + right.length; // new length char *tempPtr = new char[ newLength + 1 ]; // create memory strcpy( tempPtr, sPtr ); strcpy( tempPtr + length, right.sPtr ); delete [] sPtr; sPtr = tempPtr; length = newLength; return *this; // copy sPtr // copy right.sPtr // reclaim old space // assign new array to sPtr // assign new length to length // enables cascaded calls } // end function operator+= 2003 Prentice Hall, Inc. All rights reserved.

52 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 // is this String empty? bool String::operator!() const { return length == 0; Outline string1.cpp (4 of 8) } // end function operator! // is this String equal to right String? bool String::operator==( const String &right ) const { return strcmp( sPtr, right.sPtr ) == 0; } // end function operator== // is this String less than right String? bool String::operator<( const String &right ) const { return strcmp( sPtr, right.sPtr ) < 0; } // end function operator<

2003 Prentice Hall, Inc. All rights reserved. 53 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 // return reference to character in String as lvalue char &String::operator[]( int subscript ) { // test for subscript out of range if ( subscript < 0 || subscript >= length ) { cout << "Error: Subscript " << subscript << " out of range" << endl; exit( 1 );

Outline string1.cpp (5 of 8) // terminate program } return sPtr[ subscript ]; // creates lvalue } // end function operator[] // return reference to character in String as rvalue const char &String::operator[]( int subscript ) const { // test for subscript out of range if ( subscript < 0 || subscript >= length ) { cout << "Error: Subscript " << subscript << " out of range" << endl; exit( 1 ); // terminate program } return sPtr[ subscript ]; } // end function operator[] // creates rvalue 2003 Prentice Hall, Inc. All rights reserved. 54 131 132 133 134 135 136 137 138 139 140 141

142 143 144 145 146 147 148 149 150 151 152 153 154 155 // return a substring beginning at index and // of length subLength String String::operator()( int index, int subLength ) { // if index is out of range or substring length < 0, // return an empty String object if ( index < 0 || index >= length || subLength < 0 ) return ""; // converted to a String object automatically Outline string1.cpp (6 of 8) // determine length of substring int len; if ( ( subLength == 0 ) || ( index + subLength > length ) ) len = length - index; else len = subLength; // allocate temporary array for substring and // terminating null character char *tempPtr = new char[ len + 1 ]; // copy substring into char array and terminate string strncpy( tempPtr, &sPtr[ index ], len ); tempPtr[ len ] = '\0'; 2003 Prentice Hall, Inc. All rights reserved. 55

156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 // create temporary String object containing the substring String tempString( tempPtr ); delete [] tempPtr; // delete temporary array return tempString; Outline string1.cpp (7 of 8) // return copy of the temporary String } // end function operator() // return string length int String::getLength() const { return length; } // end function getLenth // utility function called by constructors and operator= void String::setString( const char *string2 ) {

sPtr = new char[ length + 1 ]; // allocate memory strcpy( sPtr, string2 ); // copy literal to object } // end function setString 2003 Prentice Hall, Inc. All rights reserved. 56 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 // overloaded output operator ostream &operator<<( ostream &output, const String &s ) { output << s.sPtr; return output; Outline string1.cpp (8 of 8) // enables cascading } // end function operator<<

// overloaded input operator istream &operator>>( istream &input, String &s ) { char temp[ 100 ]; // buffer to store input input >> setw( 100 ) >> temp; s = temp; // use String class assignment operator return input; // enables cascading } // end function operator>> 2003 Prentice Hall, Inc. All rights reserved. 57 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

// Fig. 8.9: fig08_09.cpp // String class test program. #include using std::cout; using std::endl; Outline fig08_09.cpp (1 of 4) #include "string1.h" int main() { String s1( "happy" ); String s2( " birthday" ); String s3; // test cout << << << << << << << << << overloaded equality and relational operators "s1 is \"" << s1 << "\"; s2 is \"" << s2 "\"; s3 is \"" << s3 << '\"' "\n\nThe results of comparing s2 and s1:" "\ns2 == s1 yields " ( s2 == s1 ? "true" : "false" ) "\ns2 != s1 yields " ( s2 != s1 ? "true" : "false" ) "\ns2 > s1 yields " ( s2 > s1 ? "true" : "false" ) 2003 Prentice Hall, Inc. All rights reserved. 58

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 << << << << << << "\ns2 < s1 yields " ( s2 < s1 ? "true" : "false" ) "\ns2 >= s1 yields " ( s2 >= s1 ? "true" : "false" ) "\ns2 <= s1 yields " ( s2 <= s1 ? "true" : "false" ); Outline fig08_09.cpp (2 of 4)

// test overloaded String empty (!) operator cout << "\n\nTesting !s3:\n"; if ( !s3 ) { cout << "s3 is empty; assigning s1 to s3;\n"; s3 = s1; // test overloaded assignment cout << "s3 is \"" << s3 << "\""; } // test overloaded String concatenation operator cout << "\n\ns1 += s2 yields s1 = "; s1 += s2; // test overloaded concatenation cout << s1; // test cout << s1 += " cout << conversion constructor "\n\ns1 += \" to you\" yields\n"; to you"; // test conversion constructor "s1 = " << s1 << "\n\n"; 2003 Prentice Hall, Inc. All rights reserved. 59 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

69 70 71 72 73 // test cout << << << overloaded function call operator () for substring "The substring of s1 starting at\n" "location 0 for 14 characters, s1(0, 14), is:\n" s1( 0, 14 ) << "\n\n"; // test cout << << << substring "to-end-of-String" option "The substring of s1 starting at\n" "location 15, s1(15, 0), is: " s1( 15, 0 ) << "\n\n"; // 0 is "to end of string" Outline fig08_09.cpp (3 of 4) // test copy constructor String *s4Ptr = new String( s1 ); cout << "\n*s4Ptr = " << *s4Ptr << "\n\n"; // test assignment (=) operator with self-assignment cout << "assigning *s4Ptr to *s4Ptr\n"; *s4Ptr = *s4Ptr; // test overloaded assignment cout << "*s4Ptr = " << *s4Ptr << '\n'; // test destructor delete s4Ptr; 2003 Prentice Hall, Inc. All rights reserved. 60

74 75 76 77 78 79 80 81 82 83 84 85 86 // test s1[ 0 ] s1[ 6 ] cout << << using subscript operator to create lvalue = 'H'; = 'B'; "\ns1 after s1[0] = 'H' and s1[6] = 'B' is: " s1 << "\n\n"; Outline fig08_09.cpp (4 of 4) // test subscript out of range cout << "Attempt to assign 'd' to s1[30] yields:" << endl; s1[ 30 ] = 'd'; // ERROR: subscript out of range return 0; } // end main 2003 Prentice Hall, Inc. All rights reserved. 61 Conversion constructor: happy

Conversion constructor: birthday Conversion constructor: s1 is "happy"; s2 is " birthday"; s3 is "" Outline fig08_09.cpp (1 of 3) The results of comparing s2 and s1: s2 == s1 yields false s2 != s1 yields true s2 > s1 yields false s2 < s1 yields true s2 >= s1 yields false s2 <= s1 yields true Testing !s3: s3 is empty; assigning s1 to s3; operator= called s3 is "happy" s1 += s2 yields s1 = happy birthday s1 += " to you" yields Conversion constructor: to you Destructor: to you s1 = happy birthday to you The constructor and destructor are called for the temporary String (converted from the char * to you). 2003 Prentice Hall, Inc. All rights reserved. 62 Conversion constructor: happy birthday Copy constructor: happy birthday Destructor: happy birthday The substring of s1 starting at location 0 for 14 characters, s1(0, 14), is: happy birthday Outline fig08_09.cpp

(2 of 3) Destructor: happy birthday Conversion constructor: to you Copy constructor: to you Destructor: to you The substring of s1 starting at location 15, s1(15, 0), is: to you Destructor: to you Copy constructor: happy birthday to you *s4Ptr = happy birthday to you assigning *s4Ptr to *s4Ptr operator= called Attempted assignment of a String to itself *s4Ptr = happy birthday to you Destructor: happy birthday to you 2003 Prentice Hall, Inc. All rights reserved. 63 s1 after s1[0] = 'H' and s1[6] = 'B' is: Happy Birthday to you Attempt to assign 'd' to s1[30] yields: Error: Subscript 30 out of range Outline fig08_09.cpp (3 of 3) 2003 Prentice Hall, Inc. All rights reserved. 64 65 8.11 Overloading ++ and - Increment/decrement operators can be overloaded Add 1 to a Date object, d1 Prototype (member function) Date &operator++(); ++d1 same as d1.operator++() Prototype (non-member)

Friend Date &operator++( Date &); ++d1 same as operator++( d1 ) 2003 Prentice Hall, Inc. All rights reserved. 66 8.11 Overloading ++ and - To distinguish pre/post increment Post increment has a dummy parameter int of 0 Prototype (member function) Date operator++( int ); d1++ same as d1.operator++( 0 ) Prototype (non-member) friend Date operator++( Data &, int ); d1++ same as operator++( d1, 0 ) Integer parameter does not have a name Not even in function definition 2003 Prentice Hall, Inc. All rights reserved. 67 8.11 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. 68 8.12 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 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // Fig. 8.10: date1.h // Date class definition. #ifndef DATE1_H #define DATE1_H #include Outline date1.h (1 of 2) using std::ostream; class Date {

friend ostream &operator<<( ostream &, const Date & ); public: Date( int m = 1, int d = 1, int y = Note 1900 difference ); // constructor between pre void setDate( int, int, int ); // set date andthe post increment. Date &operator++(); Date operator++( int ); // preincrement operator // postincrement operator const Date &operator+=( int ); // add days, modify object bool leapYear( int ) const; bool endOfMonth( int ) const; // is this a leap year? // is this end of month? 2003 Prentice Hall, Inc. All rights reserved. 69 23 24 25 26 27 28 29 30 31 32 33 34 Outline

private: int month; int day; int year; static const int days[]; void helpIncrement(); date1.h (2 of 2) // array of days per month // utility function }; // end class Date #endif 2003 Prentice Hall, Inc. All rights reserved. 70 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // Fig. 8.11: date1.cpp

// Date class member function definitions. #include #include "date1.h" Outline date1.cpp (1 of 5) // initialize static member at file scope; // one class-wide copy const int Date::days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // Date constructor Date::Date( int m, int d, int y ) { setDate( m, d, y ); } // end Date constructor // set month, day and year void Date::setDate( int mm, int dd, int yy ) { month = ( mm >= 1 && mm <= 12 ) ? mm : 1; year = ( yy >= 1900 && yy <= 2100 ) ? yy : 1900; 2003 Prentice Hall, Inc. All rights reserved. 71 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 && leapYear( year ) ) >= 1 && dd <= 29 ) ? dd : 1; >= 1 && dd <= days[ month ] ) ? dd : 1; Outline date1.cpp (2 of 5) } // end function setDate // overloaded preincrement operator Date &Date::operator++() { helpIncrement(); return *this; // reference return to create an lvalue Postincrement updates object and returns a copy of the // overloaded postincrement operator; note that the dummy original. Do not return a // integer parameter does not have a parameter name reference to temp, because it Date Date::operator++( int ) is a local variable that will be {

destroyed. Date temp = *this; // hold current state of object } // end function operator++ helpIncrement(); // return unincremented, saved, return temp; // value return; Also note that the integer temporary object parameter does not have a not a name. reference return } // end function operator++ 2003 Prentice Hall, Inc. All rights reserved. 72 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

71 72 73 74 // add specified number of days to date const Date &Date::operator+=( int additionalDays ) { for ( int i = 0; i < additionalDays; i++ ) helpIncrement(); return *this; Outline date1.cpp (3 of 5) // enables cascading } // end function operator+= // if the year is a leap year, return true; // otherwise, return false bool Date::leapYear( int testYear ) const { if ( testYear % 400 == 0 || ( testYear % 100 != 0 && testYear % 4 == 0 ) ) return true; // a leap year else return false; // not a leap year } // end function leapYear 2003 Prentice Hall, Inc. All rights reserved. 73 75 76 77 78 79 80 81 82 83

84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 // determine whether the day is the last day of the month bool Date::endOfMonth( int testDay ) const { if ( month == 2 && leapYear( year ) ) return testDay == 29; // last day of Feb. in leap year else return testDay == days[ month ]; Outline date1.cpp (4 of 5) } // end function endOfMonth // function to help increment the date void Date::helpIncrement() { // day is not end of month if ( !endOfMonth( day ) ) ++day; else // day is end of month and month < 12 if ( month < 12 ) { ++month; day = 1; } 2003 Prentice Hall, Inc. All rights reserved.

74 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 // last day of year else { ++year; month = 1; day = 1; } Outline date1.cpp (5 of 5) } // end function helpIncrement // overloaded output operator ostream &operator<<( ostream &output, const Date &d ) { static char *monthName[ 13 ] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October",

"November", "December" }; output << monthName[ d.month ] << ' ' << d.day << ", " << d.year; return output; // enables cascading } // end function operator<< 2003 Prentice Hall, Inc. All rights reserved. 75 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // Fig. 8.12: fig08_12.cpp // Date class test program. #include

fig08_12.cpp (1 of 2) using std::cout; using std::endl; #include "date1.h" Outline // Date class definition int main() { Date d1; // defaults to January 1, 1900 Date d2( 12, 27, 1992 ); Date d3( 0, 99, 8045 ); // invalid date cout << "d1 is " << d1 << "\nd2 is " << d2 << "\nd3 is " << d3; cout << "\n\nd2 += 7 is " << ( d2 += 7 ); d3.setDate( 2, 28, 1992 ); cout << "\n\n d3 is " << d3; cout << "\n++d3 is " << ++d3; Date d4( 7, 13, 2002 ); 2003 Prentice Hall, Inc. All rights reserved. 76 26 27 28 29 30 31 32 33 34 35 36 37 38 39

cout << << cout << cout << "\n\nTesting the preincrement operator:\n" " d4 is " << d4 << '\n'; "++d4 is " << ++d4 << '\n'; " d4 is " << d4; cout << << cout << cout << "\n\nTesting the postincrement operator:\n" " d4 is " << d4 << '\n'; "d4++ is " << d4++ << '\n'; " d4 is " << d4 << endl; Outline fig08_12.cpp (2 of 2) return 0; } // end main 2003 Prentice Hall, Inc. All rights reserved. 77 d1 is January 1, 1900 d2 is December 27, 1992 d3 is January 1, 1900 d2 += 7 is January 3, 1993 Outline fig08_12.cpp output (1 of 1) d3 is February 28, 1992 ++d3 is February 29, 1992 Testing

d4 is ++d4 is d4 is the preincrement operator: July 13, 2002 July 14, 2002 July 14, 2002 Testing d4 is d4++ is d4 is the postincrement operator: July 14, 2002 July 14, 2002 July 15, 2002 2003 Prentice Hall, Inc. All rights reserved. 78 8.13 Standard Library Classes string and vector Classes built into C++ Available for anyone to use string Similar to our String class vector Dynamically resizable array Redo our String and Array examples Use string and vector 2003 Prentice Hall, Inc. All rights reserved. 79 8.13 Standard Library Classes string and vector Class string

Header , namespace std Can initialize string s1(hi); Overloaded << cout << s1 Overloaded relational operators == != >= > <= < Assignment operator = Concatenation (overloaded +=) 2003 Prentice Hall, Inc. All rights reserved. 80 8.13 Standard Library Classes string and vector Class string Substring function substr s1.substr(0, 14); Starts at location 0, gets 14 characters S1.substr(15) Substring beginning at location 15 Overloaded [] Access one character No range checking (if subscript invalid) at function s1.at(10) Character at subscript 10 Has bounds checking Will end program if invalid (learn more in Chapter 13) 2003 Prentice Hall, Inc. All rights reserved. 81 1 2 3 4 5 6 7

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // Fig. 8.13: fig08_13.cpp // Standard library string class test program. #include using std::cout; using std::endl; Outline fig08_13.cpp (1 of 4) #include using std::string; int main() { string s1( "happy" ); string s2( " birthday" ); string s3; // test cout << << << << << << <<

overloaded equality and relational operators "s1 is \"" << s1 << "\"; s2 is \"" << s2 "\"; s3 is \"" << s3 << '\"' "\n\nThe results of comparing s2 and s1:" "\ns2 == s1 yields " ( s2 == s1 ? "true" : "false" ) "\ns2 != s1 yields " ( s2 != s1 ? "true" : "false" ) 2003 Prentice Hall, Inc. All rights reserved. 82 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 << << << << <<

<< << << "\ns2 > s1 yields " ( s2 > s1 ? "true" : "false" ) "\ns2 < s1 yields " ( s2 < s1 ? "true" : "false" ) "\ns2 >= s1 yields " ( s2 >= s1 ? "true" : "false" ) "\ns2 <= s1 yields " ( s2 <= s1 ? "true" : "false" ); Outline fig08_13.cpp (2 of 4) // test string member function empty cout << "\n\nTesting s3.empty():\n"; if ( s3.empty() ) { cout << "s3 is empty; assigning s1 to s3;\n"; s3 = s1; // assign s1 to s3 cout << "s3 is \"" << s3 << "\""; } // test overloaded string concatenation operator cout << "\n\ns1 += s2 yields s1 = "; s1 += s2; // test overloaded concatenation cout << s1; 2003 Prentice Hall, Inc. All rights reserved. 83 49 50 51 52 53 54 55 56 57 58

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 // test // with cout << s1 += " cout << overloaded string concatenation operator C-style string "\n\ns1 += \" to you\" yields\n"; to you"; "s1 = " << s1 << "\n\n"; // test cout << << << string member function substr "The substring of s1 starting at location 0 for\n" "14 characters, s1.substr(0, 14), is:\n" s1.substr( 0, 14 ) << "\n\n"; // test cout << << << substr "to-end-of-string" option

"The substring of s1 starting at\n" "location 15, s1.substr(15), is:\n" s1.substr( 15 ) << '\n'; Outline fig08_13.cpp (3 of 4) // test copy constructor string *s4Ptr = new string( s1 ); cout << "\n*s4Ptr = " << *s4Ptr << "\n\n"; // test assignment (=) operator with self-assignment cout << "assigning *s4Ptr to *s4Ptr\n"; *s4Ptr = *s4Ptr; cout << "*s4Ptr = " << *s4Ptr << '\n'; 2003 Prentice Hall, Inc. All rights reserved. 84 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 // test destructor delete s4Ptr; // test s1[ 0 ] s1[ 6 ] cout <<

<< using subscript operator to create lvalue = 'H'; = 'B'; "\ns1 after s1[0] = 'H' and s1[6] = 'B' is: " s1 << "\n\n"; Outline fig08_13.cpp (4 of 4) // test subscript out of range with string member function "at" cout << "Attempt to assign 'd' to s1.at( 30 ) yields:" << endl; s1.at( 30 ) = 'd'; // ERROR: subscript out of range return 0; } // end main 2003 Prentice Hall, Inc. All rights reserved. 85 s1 is "happy"; s2 is " birthday"; s3 is "" The results of comparing s2 and s1: s2 == s1 yields false s2 != s1 yields true s2 > s1 yields false s2 < s1 yields true s2 >= s1 yields false s2 <= s1 yields true Outline fig08_13.cpp output (1 of 2) Testing s3.empty(): s3 is empty; assigning s1 to s3; s3 is "happy" s1 += s2 yields s1 = happy birthday s1 += " to you" yields s1 = happy birthday to you The substring of s1 starting at location 0 for

14 characters, s1.substr(0, 14), is: happy birthday 2003 Prentice Hall, Inc. All rights reserved. 86 The substring of s1 starting at location 15, s1.substr(15), is: to you *s4Ptr = happy birthday to you Outline fig08_13.cpp output (2 of 2) assigning *s4Ptr to *s4Ptr *s4Ptr = happy birthday to you s1 after s1[0] = 'H' and s1[6] = 'B' is: Happy Birthday to you Attempt to assign 'd' to s1.at( 30 ) yields: abnormal program termination 2003 Prentice Hall, Inc. All rights reserved. 87 8.13 Standard Library Classes string and vector Class vector Header , namespace std Store any type vector< int > myArray(10) Function size ( myArray.size() ) Overloaded [] Get specific element, myArray[3] Overloaded !=, ==, and = Inequality, equality, assignment 2003 Prentice Hall, Inc. All rights reserved.

88 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 // Fig. 8.14: fig08_14.cpp // Demonstrating standard library class vector. #include Outline fig08_14.cpp (1 of 5) using std::cout; using std::cin; using std::endl; #include using std::setw; #include using std::vector; void outputVector( const vector< int > & ); void inputVector( vector< int > & );

int main() { vector< int > integers1( 7 ); vector< int > integers2( 10 ); // 7-element vector< int > // 10-element vector< int > 2003 Prentice Hall, Inc. All rights reserved. 89 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 // print integers1 size and contents cout << "Size of vector integers1 is " << integers1.size() << "\nvector after initialization:\n";

outputVector( integers1 ); Outline fig08_14.cpp (2 of 5) // print integers2 size and contents cout << "\nSize of vector integers2 is " << integers2.size() << "\nvector after initialization:\n"; outputVector( integers2 ); // input and print integers1 and integers2 cout << "\nInput 17 integers:\n"; inputVector( integers1 ); inputVector( integers2 ); cout << "\nAfter input, the vectors contain:\n" << "integers1:\n"; outputVector( integers1 ); cout << "integers2:\n"; outputVector( integers2 ); // use overloaded inequality (!=) operator cout << "\nEvaluating: integers1 != integers2\n"; 2003 Prentice Hall, Inc. All rights reserved. 90 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

67 68 69 70 71 72 if ( integers1 != integers2 ) cout << "integers1 and integers2 are not equal\n"; // create vector integers3 using integers1 as an // initializer; print size and contents vector< int > integers3( integers1 ); // copy constructor Outline fig08_14.cpp (3 of 5) cout << "\nSize of vector integers3 is " << integers3.size() << "\nvector after initialization:\n"; outputVector( integers3 ); // use overloaded assignment (=) operator cout << "\nAssigning integers2 to integers1:\n"; integers1 = integers2; cout << "integers1:\n"; outputVector( integers1 ); cout << "integers2:\n"; outputVector( integers1 ); 2003 Prentice Hall, Inc. All rights reserved. 91 73 74 75 76 77 78 79 80 81

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 // use overloaded equality (==) operator cout << "\nEvaluating: integers1 == integers2\n"; if ( integers1 == integers2 ) cout << "integers1 and integers2 are equal\n"; Outline fig08_14.cpp (4 of 5) // use overloaded subscript operator to create rvalue cout << "\nintegers1[5] is " << integers1[ 5 ]; // use overloaded subscript operator to create lvalue cout << "\n\nAssigning 1000 to integers1[5]\n"; integers1[ 5 ] = 1000; cout << "integers1:\n"; outputVector( integers1 ); // attempt to use out of range subscript cout << "\nAttempt to assign 1000 to integers1.at( 15 )" << endl; integers1.at( 15 ) = 1000; // ERROR: out of range return 0; } // end main 2003 Prentice Hall, Inc. All rights reserved. 92

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 // output vector contents void outputVector( const vector< int > &array ) { for ( int i = 0; i < array.size(); i++ ) { cout << setw( 12 ) << array[ i ]; Outline fig08_14.cpp (5 of 5) if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output cout << endl; } // end for if ( i % 4 != 0 ) cout << endl; } // end function outputVector // input vector contents void inputVector( vector< int > &array ) { for ( int i = 0; i < array.size(); i++ )

cin >> array[ i ]; } // end function inputVector 2003 Prentice Hall, Inc. All rights reserved. 93 Size of vector integers1 is 7 vector after initialization: 0 0 0 0 Size of vector integers2 is 10 vector after initialization: 0 0 0 0 0 0 Outline 0 0 0 0 0 0 0 fig08_14.cpp output (1 of 2) Input 17 integers: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 After input, the vectors contain: integers1: 1 2

3 5 6 7 integers2: 8 9 10 12 13 14 16 17 4 11 15 Evaluating: integers1 != integers2 integers1 and integers2 are not equal 2003 Prentice Hall, Inc. All rights reserved. 94 Size of vector integers3 is 7 vector after initialization: 1 2 5 6 Assigning integers2 to integers1: integers1: 8 9 12 13 16 17 integers2: 8 9

12 13 16 17 Outline 3 7 4 10 14 11 15 10 14 11 15 fig08_14.cpp output (2 of 2) Evaluating: integers1 == integers2 integers1 and integers2 are equal integers1[5] is 13 Assigning 1000 to integers1[5] integers1: 8 9 12 1000 16 17 10 14 11 15

Attempt to assign 1000 to integers1.at( 15 ) abnormal program termination 2003 Prentice Hall, Inc. All rights reserved. 95

## Recently Viewed Presentations

• This species illustrates how adaptive evolution by natural selection shapes the traits of organisms to give them niche characteristics - defined by conditions each organism prefers/tolerates. So, there is an ecological-evolutionary interplay between where a species lives and what traits...
• Rectangularly symmetric Obtainable in spherical-planar resonator by adjusting plane mirror angle Also obtainable by an intra-cavity crosswire, when the laser is operating in a multimode Indices (m,n) refer to the number of intensity minima in the x and y directions...
• Is this new system a subgroup? Q P N M Q P N M Q P N M Q P N M Q P N M Q P N M Solution The operational table is given and the system is...
• Makes up half of the brain's mass. ... (gyri) and grooves (sulci) Layers of the cerebrum. Gray matter - outer layer, composed of cell bodies. Cerebral cortex. White matter - inner layer, composed of axons (myelin makes it white. Cerebral...
• Biological Databases Genome Ontology Biology is a messy science Assortment of names, mutants, odd phenotypes "sonic hedgehog" Genome Ontology Molecular function (specific tasks) Biological process (broad biological goal) Cellular component (location) Database Searching A database can only be searched in...
• Lecture slides (including homework assignments) and Syllabus will be available through educat.nmu.edu. Slides normally will be uploaded near the end of a chapter. Attendance and Grading. Attendance will be checked randomly and will be calculated into the grade. Remember that...
• It is appropriate at any age and at any stage in a serious illness and can be provided along with curative treatment. Center to Advance Palliative Care. Death. Diagnosis of Serious Illness and . ... Describing the importance of a...
• The first sight of 'this Someone' makes John fall down at his feet as if dead! Then 'this Someone' lovingly places his hand on John's shoulder and tells him not to be afraid. He tells him that he is the...