You are on page 1of 30

Object Oriented Programming Using C++

Exceptions

Introduction

Errors can be dealt with at place error occurs


Easy to see if proper error checking implemented Harder to read application itself and see how code works Makes clear, robust, fault-tolerant programs C++ removes error handling code from "main line" of program new not allocating memory Out of bounds array subscript Division by zero Invalid function parameters

Exception handling

Common failures

Introduction (II)

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 Useful when program cannot recover but must shut down cleanly

Error Handling Error Conditions


An error condition (or just error) is a condition, occurring during runtime, that cannot be handled by the normal flow of execution. An error condition is not the same as a bug in the code.

So we are not referring to compilation errors. But some error conditions are caused by bugs. However, in our discussion of error handling, we will usually assume that our code is properly written.
Although some error conditions are caused by user mistakes. Suppose we have a function copyFile, which opens a file, reads its contents into a buffer, and writes them to another file. Function copyFile is called in order to read a file on a device that is accessed via a network. Halfway through reading the file, the network goes down. The function is supposed to read the file. This is now impossible. The normal flow of execution cannot handle this. We have an error condition.

An error condition does not mean that the user did something wrong.

Example

Basics of C++ Exception Handling: try, throw, catch

A function can throw an exception object if it detects an error

Object typically a character string (error message) or class object If exception handler exists, exception caught and handled Otherwise, program terminates

Basics of C++ Exception Handling: try, throw, catch (II)

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

The three purposes of an exception handler:


1.

2.

3.

Recover from an exception to safely continue execution If full recovery is not possible, display or log error message(s) If the exception cannot be handled locally, clean up local resources and re-raise the exception to propagate it to another handler

Exception-Handling Overview

C++ code
try { code that may raise exception } catch (exceptionType){ code to handle exception }

try block encloses code that may raise exception One or more catch blocks follow

Catch and handle exception, if appropriate Take parameter; if named, can access exception object

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

Simple Exception Handler -- Example


main() { //try Block try { throw(long(1)); //catch(long) call } //Handlers catch (int x) {cout << "Catch Integer " << x << endl;} catch (long x) {cout << "Catch Long " << x << endl;} catch (...) {cout << "Catch Rest" << endl;}
} OUTPUT WILL BE: Catch Long 1

Example 1
int main { for(int i=0; i< 5; i++){ try{
if( i< 2)
throw i; cout<<i not thrown-value is<<i<<endl; if (i >3) throw here is another; cout<<end of try block<<endl;

} catch(const int i) { cout<< i caught value is << i<<endl; } catch(const char* pmsg) { cout<<pmsg<< caught<<endl; } cout<<end of the for loop ( after the catch blocks)- i is << i<<endl;
}}

Example 2
class DivideByZeroException
{

Private: const char * message; Public: DivideByZeroException() : message( "attempted to divide by zero" ) { } const char * what() const { return message; }
};

Example 2
double quotient( int numerator, int denominator ) { // throw DivideByZeroException if trying to divide by zero if ( denominator == 0 ) throw DivideByZeroException();

// return division result return (numerator/ denominator); }

int main() { int number1, number2; double result; cout << "Enter two integers (end-of-file to end): "; while ( cin >> number1 >> number2 ) { try { result = quotient( number1, number2 ); cout << "The quotient is: " << result << endl; } catch ( DivideByZeroException ex ) { // exception handler cout << "Exception occurred: " << ex.what() << '\n'; } cout << "\nEnter two integers (end-of-file to end): "; } cout << endl; return 0; // terminate normally }

Example 2

Example cont.
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): 33 9 The quotient is: 3.66667 Enter two integers (end-of-file to end):

An Exception Handler Class Example3


class zero{ public: zero() //Constructor {cout<<"Class Zero Constructor invoked!!"<<endl;} };
//Exception Checker Function

void zero_check(int i){ if (i == 0) throw zero();


//Argument is of zero class type.

}
main()
{//try block

try{

for (int i = 2; ; i--){ zero_check(i); cout << "Reciprocal: " << 1/i << endl;}

OUTPUT : Reciprocal: 0.5 Reciprocal: 1 Class Zero Constructor Invoked!! DIVIDE BY ZERO -ERROR!!

}
//Handler

catch(zero) {cout << "DIVIDE BY ZERO -- ERROR!!\n"; exit(-1);} }

Example-4
class DivideByZeroException
{

Private: const char * message; Public: DivideByZeroException() : message( "attempted to divide by zero" ) { } const char * what() const { return message; }
};

Example-4 cont.
if ( denominator == 0 ) throw DivideByZeroException(); catch (DivideByZeroException ex ) {
// exception handler

cout << "Exception occurred: " << ex.what() << '\n';

Simple 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
Constructor can take a string (to describe exception) Member function what() returns that string

Throwing an Exception

Exception not required to terminate program

However, terminates block where exception occurred

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

Nested try Blocks


try{ try{ --------} catch( exceptionType ex) { ------------------} } catch( eceptionType ex) { -----------------------}

This handler catches the exception in the inner try block

This handler catches the exception thrown anywhere in the outer try block as well as uncaught exceptions from the inner try block

Example
int main() { for(int i=0; i<3; i++){ try{ if( i== 0) throw i; try{ if (i== 1) throw i; if (i== 2) throw static_cast<.long>(i); } catch(int i) { cout<< int exp caught inner try << i<<endl; } catch( int i) { cout<< int exp caught outer try << i<<endl; catch(long n) { cout<<long exp caught outer try<< i<<endl; }}

} }

Matching catch handler for inherited classes

The type of the parameter is a direct or indirect base class of the exception class type, or a reference to a direct or indirect base class of the exception class, ignoring const. Derived class type must appear first and the most base class type last.

Example
class trouble { Private: const char* pMsg; Public: trouble (const char* pstr=there is a problem):pMsg(pstr){} virtual const char* what() const; } const char* trouble::what() const { return pMsg; }

Example
Class moreTrouble: public Trouble { public: moreTrouble(const char* pstr=there is more trouble): trouble(pstr){ }; } Class bigTrouble: public moreTrouble { public: bigTrouble(const char* pstr=Really big trouble): moreTrouble( pstr){ }; }

int main() { Trouble tb; moreTrouble mt; big Trouble b; for (int i=0; i<5; i++) { try{ if (i<2) throw tb; if (i<4) throw mt; else throw b;} Catch(bigTrouble& rt) { cout <<Big trouble object caught<<rt.what()<<endl; } Catch(moreTrouble& rt) { cout <<moreTrouble object caught<<rt.what()<<endl;} Catch(Trouble& rt) { cout <<Trouble object caught<<rt.what()<<endl; } cout<< End of for loop value is <<i<<endl; }

Example

Example
int main() { Trouble tb; moreTrouble mt; big Trouble b; for (int i=0; i<5; i++) { try{ if (i<2) throw tb; if (i<4) throw mt; else throw b;} Catch(Trouble& rt) { cout <<Trouble object caught<<rt.what()<<endl; cout<< End of for loop value is <<i<<endl; } }

Catching an Exception

catch parameter matches thrown object when

They are of the same type 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

Catching an Exception (II)

Catch all exceptions


catch(...) - catches all exceptions

You do not know what type of exception occurred There is no parameter name - cannot reference the object

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

You might also like