Presentation is loading. Please wait.

Presentation is loading. Please wait.

© Copyright Eliyahu Brutman Programming Techniques Course Version 1.0.

Similar presentations


Presentation on theme: "© Copyright Eliyahu Brutman Programming Techniques Course Version 1.0."— Presentation transcript:

1 © Copyright Eliyahu Brutman Programming Techniques Course Version 1.0

2 © Copyright Eliyahu Brutman Chapter 12 – Exceptions Version 1.0

3 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 3 Introduction to Exception Handling Definition: An exception is any unusual event, either erroneous or not, detectable by either hardware or software, that may require special processing Without exception handling When an exception occurs, control goes to the operating system, where typically  an error message is displayed  the program is terminated With exception handling Programs are allowed to trap exceptions There is a possibility to fix the problem and continuing execution

4 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 4 Possible Naïve Solutions Exit the Program Isn ’ t it too strong OS already does the same Return Error Code Need to check the return code for every call Raise a Flag Need to check the flag after every operation Call a Special Code to Correct the Error But when shall we call it?

5 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 5 Motivation A mechanism which allows two components to survive runtime program anomaly Encountering such an anomaly (division by zero, access to an array outside its bound, etc.), may need an immediate handling The handling may reside in a different component, which we need to communicate The encountering components throws an exception The handling code, catches the exception, and handles it accordingly

6 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 6 Example Lets consider class stack const int MAX_ELEM=10; template class Stack { Tm_arr[size]; intm_index; public: Stack() : m_index(0) {} void Push(T elemP) { m_arr[m_index] = elemP; m_index++;} T& Pop() { m_index--; return m_arr[m_index]; } int Index() const { return m_index; } };

7 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 7 Exception Handling Syntax Exception Handlers try { -- code that is expected to raise an exception } catch (formal parameter) { -- handler code }...

8 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 8 Class Anomalies What happens if we pop() an empty stack? What happens if we push() on a full stack? We decide that these situations need to be handled in a special manner, since they are anomalies of the class behavior. First we define classes of exceptions which may be thrown Upon anomaly detection, we will throw an exception class popOnEmpty { /* … */ } class pushOnFull { /* … */ }

9 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 9 Example Our code would now change No need to examine the returned value for checking for success. … void Push(T elemP) { if (m_index>=size) throw pushOnFull(); // an object is throws m_arr[m_index] = elemP; m_index++;} T& Pop() { if (m_index<=0) throw popOnEmpty(); // an object is thrown m_index--; return m_arr[m_index]; } … };

10 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 10 Try…Catch Blocks Wrap the code which needs to be “ exception sensitive ”, and react to raised exceptions, in a try { … } catch { … } blocks The client ’ s code look now as following int main() { try{ Stack si; si.Pop(); si.Push(5); si.Pop(); } catch (popOnEmpty) { cout << "stack is empty !!" << endl; } };

11 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 11 Try…Catch Blocks When exception is thrown, execution resumes in the “ closest ” catch clause handling the exception. If no catch clause exists capable of handling the exception, program execution resumes at the terminate() function. Variables declared within the try block cannot be referred to at the catch clause, since they are local to the block. int main() { try{ Stack si; si.Pop(); si.Push(5); si.Pop(); } catch (popOnEmpty) { cout << "stack is empty !!" << endl; } cout << “Execution resumes here” << endl; }; Execution does Not resume here Type declaration

12 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 12 Exception-Handling Control Flow

13 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 13 Throwing Objects Why throw an object? Additional data encapsulated An object is created upon invoking the throw statement Can be created with additional data, passed to Ctor Object is destroyed after the catch clause ends

14 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 14 Stack Unwinding Up the chain of nested function calls, a suitable catch clause is searched for Upon functions and compound statements exit, stack is being unwound Lifetime of local variables ends Destructors are called If no handler is supplied, terminate() is called Since exception is a situation, where the program cannot continue execution in a normal manner By default terminate() calls abort() Similar to function call behavior But information to set up a function call is not available at compile time, run-time support is needed

15 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 15 Re-throwing and Catch All After some corrective action, a catch clause may throw an exception to be further handled, passing the exception to another catch clause, by throw. General exception handling can be specified catch( … ) { // place code here } If specified with combination, must be specified last, since evaluation is evaluated in turn.

16 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 16 Exception Specification Function interface need to be as precise as possible, it is the contract between several codes Client code may need to prepare for specific handling Best is to provide exception specification with the method declaration This will help the compiler to check consistency, to check that no other exceptions are thrown It follows the function parameter list

17 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 17 Exception Specification … void Push(T elemP) throw(pushOnFull) { if (m_index>=size) throw pushOnFull(); // an object is throws m_arr[m_index] = elemP; m_index++;} T& Pop() throw(popOnEmpty) { if (m_index<=0) throw popOnEmpty(); // an object is thrown m_index--; return m_arr[m_index]; } … };

18 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 18 Nesting try Blocks Exceptions are always handled by closest matching handler try { throw 5; } catch (int x) { cout << x << endl; // exception will be caught here } } catch (int x) { cout << x-5 << endl; }

19 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 19 Exceptions from Function Calls No different from nested try blocks Auto variables on stack are destroyed Exception jumps to nearest handler Allows exception handlers to be implemented far away from where the problem was May requires a knowledge of the issue packaged in exception object for appropriate handling

20 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 20 Exception Hierarchies Class types representing exceptions may be organized into groups or hierarchies Class Excp {} Class stackExcp : public Excp {} Class popOnEmpty : public stackExcp {} Class pushOnFull : public stackExcp {} Throwing an exception of type popOnEmpty may be caught by a handler expecting its base Therefore order should be handling more concrete types, and then handling more generic types Since handling is evaluated in order of specification, “ first match ” Ctors and Dtors are called in order like before

21 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 21 C++ Exception Hierarchy

22 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 22 Exceptions in Constructors Constructors cannot return errors Can throw exceptions Must use care! Destructors only called for fully constructed objects Subobjects (member variables that are objects) will get destroyed If memory allocated dynamically in constructor, it could get lost Exceptions are automatically rethrown from constructors

23 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 23 Exceptions Example A programmer-define ListException class #include using namespace std; class ListException: public exception { public: ListException (const string & message = “” ) : exception(message.c_str()) {} }; // end ListException

24 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 24 1 // Fig. 13.1: fig13_01.cpp 2 // A simple exception-handling example that checks for 3 // divide-by-zero exceptions. 4 #include 5 #include 6 using namespace std; 7 8 // DivideByZeroException objects should be thrown by functions 9 // upon detecting division-by-zero exceptions 10 class DivideByZeroException : public exception { 11 12 public: 13 24 // constructor specifies default error message 25 DivideByZeroException::DivideByZeroException() 26 : exception( "attempted to divide by zero" ) {} 27 28 }; // end class DivideByZeroException 29 Define new exception class (inherit from exception ). Pass a descriptive message to the constructor.

25 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 25 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 static_cast ( numerator ) / denominator; 37 } // end function quotient 38 39 int main() 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 If the denominator is zero, throw a DivideByZeroException object.

26 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 26 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; 56 } // end try 57 // exception handler handles a divide-by-zero exception 58 catch ( DivideByZeroException &divideByZeroException ) { 59 cout << "Exception occurred: " 60 << divideByZeroException.what() << endl; 61 } // end catch 62 63 cout << "\nEnter two integers (end-of-file to end): "; 64 } // end while 65 66 cout << endl; 67 return 0; // terminate normally 68 } // end main Notice the structure of the try and catch blocks. The catch block can catch DivideByZeroException objects, and print an error message. If no exception occurs, the catch block is skipped. Member function what returns the string describing the exception.

27 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 27 fig13_01.cpp output (1 of 1) Enter two integers (end-of-file to end): 100 7 The quotient is: 14.2857 Enter two integers (end-of-file to end): 100 0 Exception occurred: attempted to divide by zero Enter two integers (end-of-file to end): ^Z

28 © Copyright Eliyahu Brutman Exceptions and Design Patterns - 28 When TO Use Exceptions Fix the problem and try again Patch the problem and continue Make a complex error mechanism simpler Make code safer (catch fatal errors)


Download ppt "© Copyright Eliyahu Brutman Programming Techniques Course Version 1.0."

Similar presentations


Ads by Google