Lecture 10 Class string Exception Handling To use try, throw, and catch Constructors and destructors Standard exception hierarchy new failures Class template auto_ptr Lec 10 Programming in C++ 1 Class string Template class basic_string String manipulation (copying, searching, etc.) typedef basic_string< char > string; #include <string> using std::string string initialization string s1( "Hello" ); string s2( 8, 'x' ); 8 'x' characters string month = "March ; Implicitly calls constructor (not the assignment operator); Lec 10 Programming in C++ 2 1
string features Class string Not necessarily null terminated length member function: s1.length() Use [] to access individual characters: s1[0] 0 to length-1 string not a pointer Many member functions take start position and length Stream extraction White space delimited input. cin >> stringobject; getline(cin, s); Delimited by newline Lec 10 Programming in C++ 3 string Assignment and Concatenation Assignment s2 = s1; Makes a separate copy s2.assign(s1); Same as s2 = s1; mystring.assign(s, start, N); Copies N characters from s, beginning at index start Several overloaded versions of assign() See http://www.cplusplus.com/reference/string/string/assign.html Individual characters s2[0] = s3[2]; s2.at(0) = s3.at(2); // performs range check Lec 10 Programming in C++ 4 2
string Assignment and Concatenation Range checking s3.at( index ); Returns character at index Can throw out_of_range exception [] has no range checking Concatenation s3.append( "pet" ); s3 += "pet"; Both add "pet" to end of s3 s3.append( s1, start, N ); Appends N characters from s1, beginning at index start Other overloaded versions of append exist Lec 10 Programming in C++ 5 Comparing strings Overloaded operators ==,!=, <, >, <= and >= Return bool s1.compare(s2) Returns positive if s1 lexicographically greater Compares letter by letter 'B' lexicographically greater than 'A' Returns negative if less, zero if equal s1.compare(start, length, s2, start, length) Compare portions of s1 and s2 s1.compare(start, length, s2) Compare portion of s1 with all of s2 Lec 10 Programming in C++ 6 3
Substrings and Swapping strings Function substr gets substring s1.substr( start, N ); Gets N characters, beginning with index start Returns substring string str= "We think in generalities, but we live in details."; string str2; str2 = str.substr (12,12); // "generalities" s1.swap(s2); Switch contents of two strings Lec 10 Programming in C++ 7 Member functions string Characteristics s1.size() and s1.length() Number of characters in string s1.capacity() Number of elements that can be stored without reallocation s1.max_size() Maximum possible string size If exceeded, a length_error exception is thrown s1.empty() Returns true if empty s1.resize(newlength) Resizes string to newlength Lec 10 Programming in C++ 8 4
Finding Strings and Characters in a string Find functions If found, index returned If not found, string::npos returned Public static constant in class string s1.find( s2 ) s1.find( s2, pos ) s1.rfind( s2 ) Searches right-to-left s1.find_first_of( s2 ) Returns first occurrence of any character in s2 s1.find_first_of( "abcd" ) Returns index of first 'a', 'b', 'c' or 'd' Lec 10 Programming in C++ 9 Finding Strings and Characters in a string Find functions s1.find_last_of( s2 ) Finds last occurrence of any character in s2 s1.find_first_not_of( s2 ) Finds first character NOT in s2 s1.find_last_not_of( s2 ) Finds last character NOT in s2 Lec 10 Programming in C++ 10 5
Replacing Characters in a string s1.erase( start ) Erase from index start to end of string, including start Replace s1.replace( begin, N, s2) begin: index in s1 to start replacing N: number of characters to replace s2: replacement string s1.replace( begin, N, s2, index, num ) index: element in s2 where replacement begins num: number of elements to use when replacing Replacement can overwrite characters Lec 10 Programming in C++ 11 An Example int position = string1.find(. ); //replace all periods with two semicolons //Note: this will overwrite characters while ( position!= string::npos ) { string1.replace(position, 2, xxxxx;;yyy, 5, 2); position = string1.find(., position+1); Lec 10 Programming in C++ 12 6
Inserting Characters into a string s1.insert( index, s2 ) Inserts s2 at index It does not overwrite other characters s1.insert( index, s2, index2, N ); Inserts substring of s2 at position index Substring is N characters, starting at index2 Example: String s1( beginning end ); String s2 ( middle ); S1.insert(10, s2); cout << s1; // beginning middle end Lec 10 Programming in C++ 13 Conversion to C-Style char * Strings Conversion functions strings not necessarily null-terminated s1.copy( ptr, N, index ) Copies N characters into the array ptr Starts at location index of s1 Add explicitly null as last character s1.c_str() Returns const char * Null terminated s1.data() Returns const char * NOT null-terminated Lec 10 Programming in C++ 14 7
Iterators Iterators Forwards and backwards traversal of strings Access to individual characters Similar to pointer operations Example string s1( Testing iterators!! ); const_iterator iterator = s1.begin(); while ( iterator!= s1.end() ) { cout << *iterator; ++iterator; Lec 10 Programming in C++ 15 string Stream Processing I/O of strings to and from memory Called in-memory I/O or string stream processing #include <sstream> and <iostream> headers String input class istringstream (input from string) istringstream s( 23 56 ); int i, j; s >> i >> j; Like reading from cin. Can be used for data validation 1. Read a line to a string 2. Check the contents and repair, if needed 3. Input from the string Lec 10 Programming in C++ 16 8
String output class String Stream Processing ostringstream (output to a string) ostringstream s; s << "A number: " << setprecision(5) << sqrt(2) << endl; s << "Scientific notation: " << setw(20) << scientific << sqrt(2); cout << s.str() << endl; Take advantage of the formatting capabilities of C++ streams. Lec 10 Programming in C++ 17 Exceptions and Exception Handling Exceptions Indicates problem occurred in program Exception Handling Resolve exceptions Program may be able to continue Controlled termination Write fault-tolerant programs A divide-by-zero error Unsuccessful memory allocation Arithmetic overflow Invalid function parameters Out-of-range array subscripts Lec 10 Programming in C++ 18 9
Exception-Handling Terminology Terminology Function that has error throws an exception Exception handler (if it exists) can deal with problem Catches and handles exception If no exception handler, uncaught exception Program terminates Lec 10 Programming in C++ 19 C++ code Exception-Handling Overview try { code that may raise exception catch (exceptiontype1){ code to handle exception 1 try block encloses code that may raise exception One or more catch blocks follow Catch and handle exception, if appropriate Take parameter, to access exception object Lec 10 Programming in C++ 20 10
try { v = f(pi, i); Exception may occur in this block v *= v; catch (overflow_error &Error){ cout << Error.what() << endl; cout << v << endl; int f(double d, int i){ if ((i > 20) (d > MAX_VALUE)) throw overflow_error(); d = power(d,10); return ceil(d*fact(i)); Function terminates Local variables are destroyed Search for enclosing catch block Lec 10 Programming in C++ 21 Exception-Handling Overview Throw point Location in try block where exception occurred If exception handled Program skips remainder of try block Resumes after catch blocks If not handled Function terminates Looks for enclosing catch block If no exception Program skips catch blocks Lec 10 Programming in C++ 22 11
Exception-Handling Example: Divide by Zero Keyword throw Throws an exception Use when error occurs Can throw almost anything (exception object, integer, etc.) throw myobject; throw 5; Exception objects Base class exception ( <exception> ) Constructor can take a string (to describe exception) Member function what() returns that string Lec 10 Programming in C++ 23 1 // Fig. 13.1: fig13_01.cpp 2 // A simple exception-handling example that checks for 3 // divide-by-zero exceptions. 4 #include <iostream> 5 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 10 #include <exception> Define new exception class 11 12 using std::exception; (inherit from exception). Pass a descriptive message to 13 the constructor. 14 // DivideByZeroException objects should be thrown by functions 15 // upon detecting division-by-zero exceptions 16 class DivideByZeroException : public exception { 17 18 public: 19 20 // constructor specifies default error message 21 DivideByZeroException::DivideByZeroException() 22 : exception( Attempted to divide by zero!" ) { 23 24 ; // end class DivideByZeroException 25 Lec 10 Programming in C++ 24 12
26 // perform division and throw DivideByZeroException object if 27 // divide-by-zero exception occurs 28 double quotient( int numerator, int denominator ) 29 { 30 // throw DivideByZeroException if trying to divide by zero 31 if ( denominator == 0 ) 32 throw DivideByZeroException(); // terminate function 33 34 // return division result 35 return (double( numerator )) / denominator; 36 If the denominator is zero, throw 37 // end function quotient a DivideByZeroException 38 39 int main() object. 40 { 41 int number1; // user-specified numerator 42 int number2; // user-specified denominator 43 double result; // result of division 44 45 cout << "Enter two integers (end-of-file to end): "; 46 Lec 10 Programming in C++ 25 47 // enable user to enter two integers to divide 48 while ( cin >> number1 >> number2 ) { 49 50 // try block contains code that might throw exception 51 // and code that should not execute if an exception occurs 52 try { 53 result = quotient( number1, number2 ); 54 cout << "The quotient is: " << result << endl; 55 56 // end try 57 58 // exception handler handles a divide-by-zero exception 59 catch ( DivideByZeroException ÷byzeroexception ) { 60 cout << "Exception occurred: " 61 << dividebyzeroexception.what() << endl; 62 63 // end catch 64 65 cout << "\nenter two integers (end-of-file to end): "; 66 67 // end while 68 69 cout << endl; 70 71 return 0; // terminate normally 72 73 // end main Lec 10 Programming in C++ 26 13
Exception Specifications List of exceptions function can throw Also called throw list int somefunction( double value ) throw ( ExceptionA, ExceptionB, ExceptionC ) { // function body Can only throw ExceptionA, ExceptionB, and ExceptionC (and derived classes) If throws other type, function unexpected called By default, terminates program If no throw list, can throw any exception If empty throw list, cannot throw any exceptions Lec 10 Programming in C++ 27 Stack Unwinding If exception thrown but not caught Goes to enclosing try block Terminates current function Unwinds function call stack Looks for try/catch that can handle exception If none found, unwinds again If exception never caught Calls terminate Lec 10 Programming in C++ 28 14
int main() { try { func1(5); catch (runtime_error &error) { cout << error.what() << endl; main() return 0; func1 terminates func1(5) func2 terminates func2(5) Local variables are destroyed Space freed Destructors called func3 terminates func3(5) No try/catch that can handle the exception throw runtime_error( Error!!! ); Lec 10 Programming in C++ 29 Constructors and Exception Handling Error in constructor Example: new fails; cannot allocate memory How to inform user? Constructor cannot return a value to indicate an error Hope user examines object, notices improperly constructed object Set some global variable Good alternative: throw an exception Destructors automatically called for member objects Called for automatic variables in try block Lec 10 Programming in C++ 30 15
Destructors and Exception Handling MyObject *objptr = new MyObject[10]; try { delete [] objptr; // calls the destructor catch ( ){ code to handle exception To catch all exceptions Lec 10 Programming in C++ 31 Exceptions and Inheritance Exception classes Can be derived from base classes i.e., exception If catch can handle base class, can handle derived classes Polymorphic programming try { code that may raise exception catch (exception &error){ Can catch a reference code to handle exception to all objects of a derived class of exception Lec 10 Programming in C++ 32 16
Standard Library Exception Hierarchy Exception hierarchy Base class exception (<exception>) Virtual function what, overridden to provide error messages Sample derived classes runtime_error, logic_error bad_alloc, bad_cast Thrown by new, dynamic_cast To catch all exceptions catch(...) catch(exception &AnyException) Will not catch all possible exceptions Lec 10 Programming in C++ 33 Processing new Failures When new fails to get memory 1. Should throw bad_alloc exception Defined in <new> Compliant with C++ standard 2. Some compilers have new return 0 onn failure Not compliant with C++ standard 3. A new-handler function can be registered by the user with set_new_handler It defers the error handling to the new-handler function Lec 10 Programming in C++ 34 17
1 // Fig. 13.4: fig13_04.cpp 2 // Demonstrating pre-standard new returning 0 when memory 3 // is not allocated. 4 #include <iostream> 5 6 using std::cout; 7 8 int main() 9 { 10 double *ptr[ 50 ]; 11 12 // allocate memory for ptr 13 for ( int i = 0; i < 50; i++ ) { Demonstrating new that 14 ptr[ i ] = new double[ 5000000 ]; returns 0 on allocation 15 failure. 16 // new returns 0 on failure to allocate memory 17 if ( ptr[ i ] == 0 ) { 18 cout << "Memory allocation failed for ptr[ " 19 << i << " ]\n"; 20 21 break; 22 23 // end if 24 Lec 10 Programming in C++ 35 1 // Fig. 13.5: fig13_05.cpp 2 // Demonstrating standard new throwing bad_alloc when memory 3 // cannot be allocated. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 #include <new> // standard operator new 10 11 using std::bad_alloc; 12 13 int main() 14 { 15 double *ptr[ 50 ]; 16 17 // attempt to allocate memory 18 try { 19 Demonstrating new that 20 // allocate memory for ptr[ i ]; 21 // new throws bad_alloc on failure throws an exception. 22 for ( int i = 0; i < 50; i++ ) { 23 ptr[ i ] = new double[ 5000000 ]; 24 cout << "Allocated 5000000 doubles in ptr[ " 25 << i << " ]\n"; 26 27 28 // end try Lec 10 Programming in C++ 36 18
29 30 // handle bad_alloc exception 31 catch ( bad_alloc &memoryallocationexception ) { 32 cout << "Exception occurred: " 33 << memoryallocationexception.what() << endl; 34 35 // end catch 36 37 return 0; 38 39 // end main Lec 10 Programming in C++ 37 Processing new Failures set_new_handler Header <new> Register function to call when new fails Takes function pointer to function that Takes no arguments Returns void Once registered, function called instead of throwing exception Lec 10 Programming in C++ 38 19
1 // Fig. 13.6: fig13_06.cpp 2 // Demonstrating set_new_handler. 3 #include <iostream> 4 5 using std::cout; 6 using std::cerr; 7 8 #include <new> // standard operator new and set_new_handler 9 10 using std::set_new_handler; 11 12 #include <cstdlib> // abort function prototype The custom handler must take no arguments and return 13 14 void customnewhandler() void. 15 { 16 cerr << "customnewhandler was called"; 17 abort(); 18 19 20 // using set_new_handler to handle failed memory allocation 21 int main() 22 { 23 double *ptr[ 50 ]; 24 Lec 10 Programming in C++ 39 25 // specify that customnewhandler should be called on failed 26 // memory allocation 27 set_new_handler( customnewhandler ); 28 29 // allocate memory for ptr[ i ]; customnewhandler will be 30 // called on failed memory allocation 31 for ( int i = 0; i < 50; i++ ) { 32 ptr[ i ] = new double[ 5000000 ]; 33 34 cout << "Allocated 5000000 doubles in ptr[ " 35 << i << " ]\n"; Note call to 36 37 // end for set_new_handler. 38 39 return 0; 40 41 // end main Lec 10 Programming in C++ 40 20
Class auto_ptr and Dynamic Memory Allocation Declare pointer, allocate memory with new What if exception occurs before you can delete it? Memory leak!!! Template class auto_ptr can help us Lec 10 Programming in C++ 41 Class auto_ptr Template class auto_ptr #include <memory> Like regular pointers (has * and ->) When pointer goes out of scope, calls delete Prevents memory leaks Usage auto_ptr< MyClass > newpointer( new MyClass() ); newpointer points to dynamically allocated object Lec 10 Programming in C++ 42 21
1 // Fig. 13.7: fig13_07.cpp 2 // Demonstrating auto_ptr. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <memory> 9 10 using std::auto_ptr; // auto_ptr class definition 11 12 class Integer { 13 14 public: 15 16 // Integer constructor 17 Integer( int i = 0 ) 18 : value( i ) 19 { 20 cout << "Constructor for Integer " << value << endl; 21 22 // end Integer constructor 23 Lec 10 Programming in C++ 43 24 // Integer destructor 25 ~Integer() 26 { 27 cout << "Destructor for Integer " << value << endl; 28 29 // end Integer destructor 30 31 // function to set Integer 32 void setinteger( int i ) 33 { 34 value = i; 35 36 // end function setinteger 37 38 // function to return Integer 39 int getinteger() const 40 { 41 return value; 42 43 // end function getinteger 44 45 private: 46 int value; 47 48 ; // end class Integer 49 Lec 10 Programming in C++ 44 22
50 // use auto_ptr to manipulate Integer object 51 int main() 52 { 53 cout << "Creating an auto_ptr object that points to an " 54 << "Integer\n"; 55 56 Object created dynamically. // "aim" auto_ptr at Integer object 57 Integer* ptrtointeger = new Integer( 7 ); 58 59 cout << "\nusing the auto_ptr to manipulate the Integer\n"; 60 61 // use auto_ptr to set Integer value 62 ptrtointeger->setinteger( 99 ); 63 64 // use auto_ptr to get Integer value 65 cout << "Integer after setinteger: " 66 << ( *ptrtointeger ).getinteger() If an exception 67 << "\n\nterminating program" << endl; occurs local 68 variables, e.g. delete ptrtointeger; ptrtointeger, are 69 return 0; destroyed but memory 70 71 // end main is not deallocated. Lec 10 Programming in C++ 45 50 // use auto_ptr to manipulate Integer object 51 int main() 52 { 53 cout << "Creating an auto_ptr object that points to an " 54 << "Integer\n"; 55 56 // "aim" auto_ptr at Integer object 57 auto_ptr< Integer > ptrtointeger( new Integer( 7 ) ); 58 59 cout << "\nusing the auto_ptr to manipulate the Integer\n"; 60 61 // use auto_ptr to set Integer value 62 ptrtointeger->setinteger( 99 ); 63 64 // use auto_ptr to get Integer value 65 cout << "Integer after setinteger: " 66 << ( *ptrtointeger ).getinteger() 67 << "\n\nterminating program" << endl; 68 69 return 0; 70 71 // end main Create an auto_ptr. It can be manipulated like a regular pointer. delete not explicitly called, but the auto_ptr will be destroyed once it leaves scope. Thus, the destructor for class Integer will be called. Lec 10 Programming in C++ 46 23