1 / 83

Exception Handling

Exception Handling. Lesson #11. Note: CIS 601 notes were originally developed by H. Zhu for NJIT DL Program. The notes were subsequently revised by M. Deek. Content. Exception and Exception Handling Structure of exception handling in C++ Exception in Templates Group of exceptions Scope.

elsa
Download Presentation

Exception Handling

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Exception Handling Lesson #11 Note: CIS 601 notes were originally developed by H. Zhu for NJIT DL Program. The notes were subsequently revised by M. Deek

  2. Content • Exception and Exception Handling • Structure of exception handling in C++ • Exception in Templates • Group of exceptions • Scope

  3. Choices upon an error • Terminate immediately • Ignore the error • Set an error flag, check by the caller

  4. What is an Exception? • An error generated by the program at run-time which would normally terminate the execution of the program. • Such as, memory exhaustion, subscript range errors, or division by zero.

  5. What is Exception Handling? • A mechanism that allows a program to detect and possibly recover from errors during execution. • The alternative is to terminate the program.

  6. Common Exceptions • out-of-bound array subscript • arithmetic overflow • divide by zero • out of memory reference • invalid function parameters • etc.

  7. Benefits of Exception Handling • improved readability • easier to modify code • more robust code

  8. Without Exception Handling #include <iostream.h> #include <stdlib.h> double hmean(double a, double b); int main(void) { double x, y, z; cout << "Enter two numbers: "; while (cin >> x >> y) { z = hmean(x,y); cout << "Harmonic mean of " << x << " and " << y << " is " << z << "\n"; cout << "Enter next set of numbers <q to quit>: "; }

  9. Without Exception Handling cout << "Bye!\n"; return 0; } double hmean(double a, double b) { if (a == -b) { cout << "untenable arguments to hmean()"<<endl; abort(); } return 2.0 * a * b / (a + b); }//ex11-1.cpp

  10. With Exception Handling #include <iostream.h> #include <stdlib.h> double hmean(double a, double b); int main(void) { double x, y, z; cout << "Enter two numbers: "; while (cin >> x >> y) { try { z = hmean(x,y); } // end of try block

  11. With Exception Handling catch (const char * s) // start of exception handler { cout << s << "\n"; cout << "Enter a new pair of numbers: "; continue; } // end of handler cout << "Harmonic mean of " << x << " and " << y << " is " << z << "\n"; cout << "Enter next set of numbers <q to quit>: "; } cout << "Bye!\n"; return 0; }

  12. With Exception Handling double hmean(double a, double b) { if (a == -b) throw "bad hmean() arguments: a = -b not allowed"; return 2.0 * a * b / (a + b); }//ex11-2.cpp

  13. try { statement-list } catch(exception) { statement-list } catch(exception) { statement-list } Structure of Exception Handling

  14. Procedure for exception handling try{ func();//1.The program call in try{} } catch(Class anObj){… //3.Transfer the execution to the program } func(){ throw exObj; //2.The function throws an exception and transfer the //execution to the catch block,and assign the exObj //to anObj }

  15. Naming of an Exception #include <iostream.h> class ZeroDivide { const char* errmsg; public: ZeroDivide() : errmsg("Error: dividing by zero") { } void print() { cout << errmsg; } }; float divide(int n1, int n2); void main() { int a, b; cout <<"Input two integers:";

  16. Naming cin >> a >> b; try { float c = divide(a,b); cout << "a / b = " << c << '\n'; } catch (ZeroDivide err) { err.print(); } cout <<“\n”<< "end of program\n"; } float divide(int n1, int n2) { if (n2 == 0) throw ZeroDivide(); return (float) n1 / n2; }//ex11-3.cpp Results: Input two integers:34 0 Error: dividing by zero end of program

  17. Example #include <iostream.h> const unsigned ArraySize = 50; int array[ArraySize]; class RangeError{}; void InsertValue(unsigned i, int value) { if (i>=ArraySize) throw RangeError(); array[i] = value; } void TestTheArray() { unsigned j ; int anInt; cout <<"Enter a subscript and a value:";

  18. Example cin >> j >> anInt; InsertValue(j, anInt); } void main() { try { TestTheArray(); } catch (const RangeError &) { cout <<"Range Error in main()!"<< endl; } }//ex11-4.cpp

  19. Passing Data with Exceptions #include <iostream.h> class array { int* v, lower, upper; public: class SubscriptError { int index; public: SubscriptError(int i) : index(i) { }; int get() { return index; }; }; array(int l, int u):lower(l), upper(u){ v = new int [upper-lower +1]; }; int& operator[](int); ~array(){delete [] v;} };

  20. int& array::operator[](int i) { if (i>=lower && i<=upper) return *(v+i-lower); throw SubscriptError(i); return *v; }; void fun(array& a) { try { a[100]; } catch (array::SubscriptError s) { cerr <<"illegal subscript:" <<s.get() << '\n'; } } void main() { array ar(20, 40); fun (ar); }//ex-5.cpp

  21. More than One Exception const MAX = 500; class array { int* v, lower, upper; public: //… class SizeError {}; array(int l, int u):lower(l), upper(u){ int size = upper-lower+1; if (size<0 || size>MAX) throw SizeError(); else { v = new int[size]; } }; }; If we add another exception SizeError, how is it done?

  22. More than One Exception void main() { int l, u; try { cout << "Input two bounds for the array:"; cin >> l>>u; array ar(l, u); fun (ar); } catch (array::SizeError ){ cerr <<"illegal size:" <<u - l +1 << '\n'; } }//ex11-6.cpp

  23. Unwinding the Exception Stack • Stack unwinding: • When a program throw an exception, the destructor is called for each object that was constructed when the program entered the try block.

  24. Unwinding the Exception Stack • When an exception is thrown during the construction of a composite object, destructors will be invoked only for those data members that have already been constructed.

  25. Unwinding #include <iostream.h> #include <string.h> class Test{}; class VString{ public: VString(){ }; VString(char *s){ }; ~VString(){cout <<"VString Des!"<<endl;}; }; class Transcript{ public: Transcript(){ throw Test(); }; ~Transcript(){cout <<"Transcript Des!"<<endl;}; };

  26. Unwinding class Student{ VString lastName; Transcript records; public: Student(){}; ~Student(){cout <<"Student Des!"<<endl;}; }; void main() { try{ VString collegeName("NJIT"); Student S; } catch (...) {cout << "exception!"<<endl; } }//ex11-7.cpp

  27. Multiple Handlers • Most programs performing exception handling have to handle more than one type of exception. A single try block can be followed by multiple handlers(catch), each configured to match a different exception type.

  28. Example #include <stdio.h> #include <iostream.h> #include <fstream.h> class RangeError { }; //Exception class InputFileError { }; //Exception class LongArray { public: LongArray( unsigned sz = 0 ); ~LongArray(); long Get( unsigned i ) const; private: long * data; // array of long integers unsigned size; // allocation size };//cis601source/chap8/except/except2.cpp

  29. Example LongArray::LongArray( unsigned sz ) { size = sz; data = new long[size]; } LongArray::~LongArray() { delete [] data;} long LongArray::Get( unsigned i ) const { if( i >= size ) throw RangeError(); return data[i]; }

  30. Example unsigned ArraySize = 50; void ReadFile( ifstream & infile, LongArray & L ) { infile.open( "INDATA.TXT" ); if( !infile ) throw InputFileError(); } void GetArrayElement( const LongArray & L ) { unsigned i; cout << "Enter subscript: "; cin >> i; long n = L.Get( i ); }

  31. Example int main() { try { ifstream infile; LongArray L( ArraySize ); ReadFile( infile, L ); GetArrayElement( L ); cout << "Program completed normally.\n"; } catch( const RangeError & R ) { cout << "Subscript out of range\n"; } catch( const InputFileError & F ) { cout << "Unable to open input file\n"; } catch( ... ) { cout << "Unknown exception thrown\n"; } return 0; }//except2.cpp

  32. Results Enter subscript: 23 Program completed normally. Enter subscript: 56 Subscript out of range

  33. Ex: RangeError Class #include <iostream.h> #include <stdlib.h> #include <fstream.h> #include "fstring.h" #include "range.h" class LongArray { public: LongArray( unsigned sz = 0 ){size = sz; data = new long [sz];}; ~LongArray() {delete [] data;}; unsigned GetSize() const; long Get( unsigned i ) const; void Put( unsigned i, long item ); private: long * data; // array of long integers unsigned size; // allocation size }; //cis601source/chap8/except/except3.cpp

  34. Range.h #include <iostream.h> #include <string.h> const unsigned FileNameSize = 50; // Make this >= longest filename on target system. class RangeError { public: RangeError( const char * fname, unsigned line, unsigned subscr ) { strncpy(fileName, fname, FileNameSize); lineNumber = line; value = subscr; }

  35. Range.h friend ostream & operator <<( ostream & os, const RangeError & R ) { os << "\nRangeError exception thrown: " << R.fileName << ", line " << R.lineNumber << " value = " << R.value << endl; return os; } private: char fileName[FileNameSize+1]; unsigned lineNumber; unsigned value; };

  36. The name of the current source file. __FILE__ expands to a string surrounded by double quotation marks. RangeError inline unsigned LongArray::GetSize() const { return size;} inline void LongArray::Put( unsigned i, long item ) { if( i >= size ) throw RangeError( __FILE__ ,__LINE__, i ); data[i] = item; } inline long LongArray::Get( unsigned i ) const { if( i >= size ) throw RangeError( __FILE__ ,__LINE__, i ); return data[i]; } The line number in the current source file. The line number is a decimal constant.

  37. RangeError unsigned GetArraySize() { unsigned n; cout << "Number of array elements? "; cin >> n; return n; } void FillArray( LongArray & L ) { int i; try { for( i = 0; i < L.GetSize(); i++ ) L.Put( i, rand() ); } catch( const RangeError & R ) { cout << R; throw R; } }

  38. RangeError void GetArrayElement( const LongArray & L ) { int ok = 0; while( !ok ) { unsigned i; cout << "Enter an array subscript (0-"<< ( L.GetSize()-1 ) << "): "; cin >> i; long n; try { n = L.Get( i ); ok = 1; cout << "Element contains " << n << endl; } catch( const RangeError & R ) { cout << R; cout << "Caught at: " << __FILE__<< ", line " << __LINE__ << endl; throw; } } }

  39. RangeError int main() { try { LongArray L( GetArraySize() ); FillArray( L ); GetArrayElement( L ); } catch( ... ) { cout << "Exception caught in main().\n"; return 1; } return 0; }//except3.cpp

  40. Exception with no Catch • If no catch matches the exception generated by the try block, the search continues with the next enclosing try block. • If no catch is found, then error!

  41. void fun1(array& a) { ... try { fun2(a); ... } catch (array::SubscriptError) { ... } ... }

  42. void fun2(array& a) { ... try { ... // use array a } catch (array::SizeError) { ... } ... }

  43. Exception within an Exception • If the same exception type is raised while handling the exception of a try block, then the new exception is handled by the outer try block.

More Related