Presentation is loading. Please wait.

Presentation is loading. Please wait.

Why exception handling in C++?

Similar presentations


Presentation on theme: "Why exception handling in C++?"— Presentation transcript:

1 Why exception handling in C++?
Exception handling is better makes clear, robust, fault-tolerant programs C++ removes error handling code from "main line" of program Exception handling - catch errors before they occur deals with synchronous errors (i.e., divide by zero) does not deal with asynchronous errors - disk I/O completions, mouse clicks - use interrupt processing used when system can recover from error exception handler - recovery procedure typically used when error is dealt with in different place than where it occurred useful when program cannot recover but must shut down cleanly Exception handling should not be used for program control not optimized, can harm program performance Exception handling should be used for processing exceptional situations processing exceptions for components that cannot handle them directly processing exceptions for widely used components (libraries, classes, functions) that should not process their own exceptions large projects that require uniform error processing

2 Here’s an example of exception handling:
vector <double> realvec(5); /* run through the vector and display each element, if possible */ for (int i =0; i<10; i++) { try { cout << "Element " << i << ": " << realvec.at(i) << endl; } catch (exception& e) { cout << "Element " << i << ": index exceeds vector dimensions." << endl; The method vector::at throws an out of range exception if the index is out of range. The other accessor vector::operator[] does not.

3 Let’s take a careful look: Exception Handling: try, throw, catch
A function can throw an exception object if it detects an error object is typically a character string (error message) or class object if exception handler exists, exception caught and handled otherwise, program terminates Format enclose code that may have an error in try block follow with one or more catch blocks each catch block has an exception handler if exception occurs and matches parameter in catch block, code in catch block executed if no exception thrown, exception handlers skipped and control resumes after catch blocks throw point - place where exception occurred control cannot return to throw point

4 Example: Division by Zero (credit Deitel & Deitel)
// An exception-handling example that checks for divide-by-zero exceptions. #include <iostream> #include <exception> using namespace std; // DivideByZeroException objects should be thrown by functions // upon detecting division-by-zero exceptions class DivideByZeroException : public exception { public: // constructor specifies default error message DivideByZeroException::DivideByZeroException() : exception( "attempted to divide by zero" ) {} }; // end class DivideByZeroException // a function that performs division and throws DivideByZeroException object if // divide-by-zero exception occurs double quotient( int numerator, int denominator ) { // throw DivideByZeroException if trying to divide by zero if ( denominator == 0 ) throw DivideByZeroException(); // terminate function // return division result return static_cast< double >( numerator ) / denominator; } // end function quotient The function quotient is defined to throw an exception object if denominator == 0

5 int main() { int number1; // user-specified numerator int number2; // user-specified denominator double result; // result of division cout << "Enter two integers (end-of-file to end): "; // enable user to enter two integers to divide while ( cin >> number1 >> number2 ) { try { result = quotient( number1, number2 ); cout << "The quotient is: " << result << endl; } // end try catch ( DivideByZeroException &divideByZeroException ) { cout << "Exception occurred: " << divideByZeroException.what() << endl; } // end catch cout << "\nEnter two integers (end-of-file to end): "; } // end while cout << endl; return 0; // terminate normally } // end main try block encloses code that may throw an exception, along with code that should not execute if an exception occurs. catch block follows try block, and contains exception-handling code.

6 Let’s look at this in a little more depth
throw - indicates an exception has occurred usually has one operand (sometimes zero) of any type if operand an object, called an exception object conditional expression can be thrown code referenced in a try block can throw an exception exception caught by closest matching exception handler control exits current try block and goes to catch handler (if it exists) Example (inside function definition): if ( denominator == 0 ) throw DivideByZeroException(); throws a DivideByZeroException object Exception does not have to terminate the program it does, however, terminate the block where exception occurred

7 Catching an Exception Exception handlers are in catch blocks
Format: catch( exceptionType parameterName){ exception handling code } caught if argument type matches throw type if not caught then terminate called which (by default) calls abort Example: catch ( DivideByZeroException ex) { cout << "Exception occurred: " << ex.what() <<'\n' catches exceptions of type DivideByZeroException To catch all exceptions catch(...) - catches all exceptions potentially thrown in a try block Weaknesses of this use: you do not know what type of exception occurred there is no parameter name - cannot reference the object

8 Catching an Exception (cont.)
If no handler matches thrown object searches next enclosing try block if none found, terminate called if found, control resumes after last catch block if several handlers match thrown object, first one found is executed catch parameter matches thrown object when they are of the same type exact match required - no promotions/conversions allowed the catch parameter is a public base class of the thrown object the catch parameter is a base-class pointer/ reference type and the thrown object is a derived-class pointer/ reference type of that base the catch handler is catch( ... ) thrown const objects have const in the parameter type

9 Catching an Exception (cont.)
Unreleased resources resources may have been allocated when exception thrown catch handler should delete space allocated by new and close any opened files catch handlers can throw exceptions exceptions can only be processed by outer try blocks When a catch handler finishes executing, any local variables defined in it (including the catch parameter) go out of scope; any succeeding catch handlers are ignored, and execution continues at the first line of code after the try/catch sequence If no exception occurs in a try block, the catch handlers are ignored.

10 Recap – exception handling so far: throw, try, and catch
-- code that is expected to raise an exception along with code that should not be executed if the exception is raised } catch (formal parameter) { -- handler code ... try { result = quotient( number1, number2 ); cout << "The quotient is: " << result << endl; } // end try catch ( DivideByZeroException &divideByZeroException ) { cout << "Exception occurred: " << divideByZeroException.what() << endl; } // end catch

11 Some observations: catch is the name of all handlers--it is an overloaded name in C++ , so the formal parameter of each catch block must be unique The formal parameter does not need to have a variable It can be simply a type name to distinguish the handler it is in from others The formal parameter can be used to transfer information to the handler The formal parameter can be an ellipsis (…), in which case it handles all exceptions not yet handled

12 Exception Handling: One more Recap
C++ has a built in error handling mechanism: exception handling Program statements you want to monitor are put into a try blocks If an exception occurs in the try block, an exception is thrown (using throw) The exception is caught using catch and processed The general form is as follows try { // try block } catch (type1 arg) { // catch block catch (type2 arg) {  The general form of the throw statement is as follows: throw ex; When an exception is thrown it is caught by the corresponding catch statement

13 Rules for throwing exceptions
throw has to be executed: From within the try block itself From a function called from within the try block (either directly or indirectly) The value that is thrown is the value of the argument There may be multiple catch blocks associated with a given try block They have to immediately follow the try block If you throw an exception for which there is no matching catch block, the program may abort

14 Example: #include "stdafx.h" #include <iostream>
#include <exception> using namespace System; using namespace std; int main(array<System::String ^> ^args) { cout << "Begin the example \n"; try { // beginning of the try block cout << "Inside the try block now \n"; throw 10; // throw an error cout << "This line should never print out \n"; } catch (int i) { // catch an error cout << "caught error number " << i << endl; cout << "Next statement after the catch block \n"; return 0; Once an exception has been thrown, control passes to the catch expression The try block is terminated After the catch executes control passes to the statement after the catch

15 An exception can be thrown from a statement outside the try block as long as it is in a function called from inside the try block // same includes as in first example today void foo (int test) { cout << "Inside foo, test is " << test << endl; if (test) throw test; } int main(array<System::String ^> ^args) cout << "Begin indirect throw \n \n"; try { // start of try block cout << "Inside the try block " << endl; foo (0); foo (1); foo (2); catch (int i) { // catch an error cout << "caught error number " << i << endl; cout << "Next statement after the catch block \n"; return 0; What happens here? foo(0) called print msg from inside foo test = 0 = false nothing thrown so return from foo foo (1) called test = 1 = true throw value of 1 catch the exception print from catch block exit catch block execute stmt after catch block

16 Using multiple catch statements
void bar (int test) { try { if (test) throw test; else throw "Hi there!"; } catch (int i) { // catch an error cout << "caught error number " << i << endl; catch (char *str) {cout << "caught a string " << str << endl; int main(array<System::String ^> ^args) { cout << "Starting example 3 \n \n"; bar(1); bar(2); bar(0); bar(7); cout << "Last statement in main \n"; return 0; }

17 Catching all exceptions
Sometimes you want a handler that will catch any old exception This is done using the ellipsis: catch (…) { // code to deal with exceptions } The example on the next slide illustrates use of this

18 Use of ellipsis catch blocks
void baz (test) { try { if (test == 0) throw test; // int if (test == 1) throw 'x'; // char if (test == 2) throw ; } catch (int i) { // catch an int exception cout << "Caught the int " << i << endl; catch (...) cout << "caught something, don't know what \n"; int main(array<System::String ^> ^args) { cout << "Starting example 4 \n \n"; baz(0); baz(1); baz(2); cout << "Last statement in main \n"; return 0; }


Download ppt "Why exception handling in C++?"

Similar presentations


Ads by Google