2. • Exception handling allows us to manage
run-time errors in an orderly fashion
• program can automatically invoke an
error-handling routine when an error
occurs.
• Advantage:
– Automation of error-handling code
3. Exception Handling Fundamentals
• three basic keywords: try, catch, and throw.
• program statements that you want to monitor for
exceptions are contained in a try block.
• If an exception (i.e., an error) occurs within the
try block, it is thrown (using throw).
• Functions called from within a try block may also
throw an exception.
• The exception is caught, using catch, and
processed.
5. Handling Exceptions
• When an exception is thrown, it is caught
by its corresponding catch statement.
• There can be more than one catch
statement associated with a try.
• If the data type specified by a catch
matches that of the exception, then that
catch statement is executed (and all
others are bypassed).
6. Unhandled Exceptions
• If there is no applicable catch statement,
an abnormal program termination may
occur.
• For an unhandled exception, standard
library function terminate() is invoked.
• By default, terminate() calls abort() to
stop the program
7. Example:
#include <iostream>
using namespace std;
int main()
{
cout << "Startn";
try { // start a try block
cout << "Inside try blockn";
throw 100; // throw an error
cout << "This will not execute";
}
catch (int i) { // catch an error
cout << "Caught an exception --
value is: ";
cout << i << "n";
}
cout << "End";
}
• Output:
Start
Inside try block
Caught an exception -- value is:
100
End
8. • Once an exception has been thrown, control passes to the
catch expression and the try block is terminated.
• catch is not called. Rather, program execution is
transferred to it.
• The program's stack is automatically reset.
• The statements following the throw will never execute.
• If the error can be fixed, execution will continue after catch,
else a catch block will terminate the program with a call to
exit() or abort() .
9. The type of the exception must match the type specified in a catch
statement
The exception will not be caught and abnormal termination will
occur
#include <iostream>
using namespace std;
int main()
{
cout << "Startn";
try { // start a try block
cout << "Inside try blockn";
throw 100; // throw an error
cout << "This will not execute";
}
catch (double i) { // won't work for an int
exception
cout << "Caught an exception -- value is: ";
cout << i << "n";
}
cout << "End";
return 0;
}
Output
Start
Inside try block
Abnormal program termination
10. Throwing an exception from a function outside the
try block.
#include <iostream>
using namespace std;
void Xtest(int test)
{
cout << "Inside Xtest, test is: " << test << "
n";
if(test) throw test;
}
int main()
{
cout << "Startn";
try { // start a try block
cout << "Inside try blockn";
Xtest(0);
Xtest(1);
Xtest(2);
}
catch (int i) { // catch an error
cout << "Caught an exception -- value is: ";
cout << i << "n";
}
cout << "End";
return 0;
}
Output:
Start
Inside try block
Inside Xtest, test is: 0
Inside Xtest, test is: 1
Caught an exception -- value is: 1
End
11. Local try block
#include <iostream>
using namespace std;
// Localize a try/catch to a function.
void Xhandler(int test)
{
try{
if(test) throw test;
}
catch(int i) {
cout << "Caught Exception #: " << i << 'n';
}
}
int main()
{
cout << "Startn";
Xhandler(1);
Xhandler(2);
Xhandler(0);
Xhandler(3);
cout << "End";
return 0;
}
Output:
Start
Caught Exception #: 1
Caught Exception #: 2
Caught Exception #: 3
End
12. Catching Class Types
• Generally an exception can be of any type.
• In real-world programs, most exceptions
will be class types rather than built-in
types.
• common reason - to create an object that
describes the error.
• It can be used by the exception handler to
help it process the error.
13. // Catching class type exceptions.
#include <iostream>
#include <cstring>
using namespace std;
class MyException {
public:
char str_what[80];
int what;
MyException() { *str_what = 0; what = 0; }
MyException(char *s, int e) {
strcpy(str_what, s);
what = e;
}
};
int main()
{
int i;
try {
cout << "Enter a positive number: ";
cin >> i;
if(i<0)
throw MyException("Not Positive", i);
}
catch (MyException e) { // catch an error
cout << e.str_what << ": ";
cout << e.what << "n";
}
return 0;
}
Output:
Enter a positive number: -4
Not Positive: -4
14. Using Multiple catch Statements
• There can be more than one catch
associated with a try.
• Each catch must catch a different type of
exception.
15. #include <iostream>
using namespace std;
// Different types of exceptions can be
caught.
void Xhandler(int test)
{
try{
if(test) throw test;
else throw "Value is zero";
}
catch(int i) {
cout << "Caught Exception #: " << i << 'n';
}
catch(const char *str) {
cout << "Caught a string: ";
cout << str << 'n';
}
}
int main()
{
cout << "Startn";
Xhandler(1);
Xhandler(2);
Xhandler(0);
Xhandler(3);
cout << "End";
return 0;
}
Output:
Start
Caught Exception #: 1
Caught Exception #: 2
Caught a string: Value is zero
Caught Exception #: 3
End
16. Handling Derived-Class Exceptions
• order of catch statements is most
important while inheriting.
• because a catch clause for a base class
will also match any class derived from that
base.
• to catch exceptions of both a base class
and a derived class, put the derived class
first in the catch sequence.
17. // Catching derived classes.
#include <iostream>
using namespace std;
class B {
};
class D: public B {
};
int main()
{
D derived;
try {
throw derived;
}
catch(B b) {
cout << "Caught a base class.n";
}
catch(D d) {
cout << "This won't execute.n";
}
return 0;
}
• In this example the catch clause of the
base class will always be executed.
• reverse the order of the catch clauses
18. Exception Handling Options
Additional features and nuances that make it
easier and more convenient to use are,
• Catching All Exceptions
• Restricting Exceptions
• Rethrowing an Exception
19. Catching All Exceptions
• This catch block will catch all kind of
exceptions
• Syntax:
catch(...) {
// process all exceptions
}
20. // This example catches all exceptions.
#include <iostream>
using namespace std;
void Xhandler(int test)
{
try{
if(test==0) throw test; // throw int
if(test==1) throw 'a'; // throw char
if(test==2) throw 123.23; // throw double
}
catch(...) { // catch all exceptions
cout << "Caught One!n";
}
}
int main()
{
cout << "Startn";
Xhandler(0);
Xhandler(1);
Xhandler(2);
cout << "End";
return 0;
}
Output:
Start
Caught One!
Caught One!
Caught One!
End
21. This block can be made the last catch block to catch all the
left out exceptions
// This example uses catch(...) as a
default.
#include <iostream>
using namespace std;
void Xhandler(int test)
{
try{
if(test==0) throw test; // throw int
if(test==1) throw 'a'; // throw char
if(test==2) throw 123.23; // throw double
}
catch(int i) { // catch an int exception
cout << "Caught an integern";
}
catch(...) { // catch all other exceptions
cout << "Caught One!n";
}
}
int main()
{
cout << "Startn";
Xhandler(0);
Xhandler(1);
Xhandler(2);
cout << "End";
return 0;
}
OUTPUT:
Start
Caught an integer
Caught One!
Caught One!
End
22. Restricting Exceptions
• Exceptions thrown outside the functions
can be restricted.
• To accomplish these restrictions, you must
add a throw clause to a function definition.
23. • Syntax:
ret-type func-name(arg-list) throw(type-list)
{
//..
}
• Only the types specified in the type-list can be thrown as
exceptions.
• Throwing any other type of expression will cause abnormal
program termination
• Attempting to throw an exception that is not supported by a function
will cause the standard library function unexpected() to be called
unexpected() -> abort()
24. // Restricting function throw types.
#include <iostream>
using namespace std;
// This function can only throw ints, chars,
and doubles.
void Xhandler(int test) throw(int, char,
double)
{
if(test==0) throw test; // throw int
if(test==1) throw 'a'; // throw char
if(test==2) throw 123.23; // throw double
}
int main()
{
cout << "startn";
try{
Xhandler(0); // also, try passing 1 and 2 to
Xhandler()
}
catch(int i) {
cout << "Caught an integern";
}
catch(char c) {
cout << "Caught charn";
}
catch(double d) {
cout << "Caught doublen";
}
cout << "end";
return 0;
}
25. // This function can throw NO exceptions!
void Xhandler(int test) throw()
{
/* The following statements no longer work. Instead, they
will cause an abnormal program termination. */
if(test==0) throw test;
if(test==1) throw 'a';
if(test==2) throw 123.23;
}
26. Rethrowing an Exception
• An exception can be thrown back, by
calling throw, by itself, with no exception.
• the current exception to be passed on to
an outer try/catch sequence.
• This allows multiple handlers access to the
exception.
27. // Example of "rethrowing" an
exception.
#include <iostream>
using namespace std;
void Xhandler()
{
try {
throw "hello"; // throw a char *
}
catch(const char *) { // catch a
char *
cout << "Caught char * inside
Xhandlern";
throw ; // rethrow char * out of
function
}
}
int main()
{
cout << "Startn";
try{
Xhandler();
}
catch(const char *) {
cout << "Caught char * inside
mainn";
}
cout << "End";
return 0;
}
Output:
Start
Caught char * inside Xhandler
Caught char * inside main
End
28. Understanding terminate() and unexpected()
• These functions are supplied by the
Standard C++ library
• These functions require the header
<exception>.
• Prototypes
– void terminate( );
– void unexpected( );
29. • The terminate() function is called whenever program
attempts to rethrow an exception when no exception was
originally thrown.
• Eg:
Unwinding the stack because of an exception, a
destructor for an object may throw an exception
• terminate() is the handler of last resort when no other
handlers for an exception are available.
terminate() -> abort()
30. • The unexpected() function is called when a
function attempts to throw an exception
• that is not allowed by its throw
unexpected() -> terminate() .
31. Setting the Terminate and Unexpected
Handlers
• Syntax:
terminate_handler set_terminate(terminate_handler newhandler) throw();
unexpected_handler set_unexpected(unexpected_handler newhandler) throw();
Both set_terminate() and set_unexpected() require the
header <exception>.
32. // Set a new terminate handler.
#include <iostream>
#include <cstdlib>
#include <exception>
using namespace std;
void my_Thandler() {
cout << "Inside new terminate handlern";
abort();
}
int main()
{
// set a new terminate handler
set_terminate(my_Thandler);
try {
cout << "Inside try blockn";
throw 100; // throw an error
}
catch (double i) { // won't catch an int exception
// ...
}
return 0;
}
Output:
Inside try block
Inside new terminate handler
abnormal program termination
33. The uncaught_exception( ) Function
bool uncaught_exception( );
True -> if an exception has been thrown
but not yet caught.
False -> Exception is caught.
34. The exception and bad_exception Classes
• Exceptions thrown by C++ standard library will be object
derived from the base class exception.
• An object of the class bad_exception can be thrown by
the unexpected handler
• These classes require the header <exception.h>.
35. Applying Exception Handling
• Exception handling is designed to provide a
structured means to handle abnormal events.
• The error handler must do something rational
when an error occurs.
36. #include <iostream>
using namespace std;
void divide(double a, double b);
int main()
{
double i, j;
do {
cout << "Enter numerator (0 to
stop): ";
cin >> i;
cout << "Enter denominator: ";
cin >> j;
divide(i, j);
} while(i != 0);
return 0;
}
void divide(double a, double b)
{
try {
if(!b) throw b; // check for divide-by-zero
cout << "Result: " << a/b << endl;
}
catch (double b) {
cout << "Can't divide by zero.n";
}
}