OOP - Chapter 10 Exception Handling
OOP - Chapter 10 Exception Handling
EXCEPTION HANDLING
CHAPTER 10
05 Re-throwing Exception
We often come across some peculiar problems other than logic and syntax errors.
They are known as exceptions.
Exceptions are run time anomalies or unusual conditions that a program may
encounter while executing. E.g. Division by zero,access to an array outside its
bound, running out of memory or disk space etc.
The purpose of the exception handling mechanism is to provide means to detect
and report “exceptional circumstances” so that appropriate action can be taken.
EXCEPTION HANDLING CONSTRUCTS
( TRY, CATCH, THROW)
Exceptions are the anomalous or unusual events that change the normal flow of the
program. Exception handling is the mechanism by which we can identify and deal
with such unusual conditions. This mechanism suggests a separate error handling
code that performs the following tasks:
1. Find the problem (Hit the exception).
2. Inform that an error has occurred (Throw the exception).
3. Receive the error information ( Catch the exception).
4. Take corrective actions (Handle the exception).
The error handling code basically consists of two segments, one to detect errors and
to throw the exception, and the other to catch the exception and to take corrective
actions.
CONSTRUCTS OF EXCEPTION HANDLING
In C++, the following keywords are used for exception handling.
a) try
b) catch
c) throw
1. The keyword try is used to preface a block of
statements (surrounded by braces) which may
generate exceptions. This block of statements
is known as try block. When an exception is
detected, it is thrown using a throw statement
in the try block.
2. A catch block defined by the keyword catch is
used to catch the exception thrown by the
throw statement in the try block, and handles
it properly.
CONSTRUCTS OF EXCEPTION HANDLING
The catch block that catches the exception must immediately follow the try block that throws the
exception. The general form of these two blocks are as follows:
………..
………..
try
{
………. // block of statements which detects and
throw exception; // throws an exception.
………..
………..
}
catch (type arg)
{
………… // block of statements that handles the exception
………… // thrown by the try block.
…………
}
…………
CONSTRUCTS OF EXCEPTION HANDLING
Try keyword is used to a block of statements surrounded by braces which may generate
exceptions. When an exception is detected, it is thrown using the throw statement in try
block, then the program control leaves the try block and enters the catch block
comparing the catch argument try and the exception thrown type. If the type of the
object matches the argument type in the catch statement, then the catch block is
executed for handling the exception. If they don't match, the program is aborted with
the help of the abort() function which is invoked by default. When no exception is
detected and thrown, the control goes to the statement immediately after the catch
block i.e. catch block is skipped. In handling exceptions we need to create a new kind of
entity called an exception class.
CONSTRUCTS OF EXCEPTION HANDLING
#include<iostream>
catch(int i)
using namespace std;
{
int main()
cout<<”Division by zero. X = ”<<i<<endl;
{
}
int a,b,x;
return 0;
cout<<”Enter the values of a and b: ”;
}
cin>>a>>b;
x = a-b;
try Output:
{ Enter the values of a and b: 4 2
if(x!=0) The result of (a/x) is 2.
cout<<”The result of (a/x) is ”<<a/x<<endl;
else Output 2:
throw(x);
Enter the values of a and b: 8 8
}
Division by zero. X = 0
ADVANTAGE OVER CONVENTIONAL ERROR HANDLING
The error handling mechanism is somewhat new and very convenient in case of object
oriented approach over conventional programming. When an error is detected, the error
could be handled locally or not locally. Traditionally, when the error is not handled locally
the function could
1. Terminate the program.
2. Return a value that indicates error.
3. Return some value and set the program in an illegal state.
try
{
//try block
}
catch(type1 arg)
{
//catch block1
}
………..
………..
catch(typeN arg)
{
//catch blockN
}
MULTIPLE EXCEPTION HANDLING
#include<iostream> catch(double c)
using namespace std; {
void test(int a, int b) cout<<"\nSecond operand is equal to zero"<<endl;
{ cout<<”caught a double”<<endl;
try }
{ cout<<”End of try-catch system”<<endl;
if (b < 0) }
throw b; Output:
if(b == 0) int main()
The Quotient = 4
throw 1.1; {
End of try block
cout << "The Quotient = " << (a/b) << endl; test(12,3);
cout<<”End of try block”<<endl; test(12, -3); End of try-catch system
} test(12,0); Second Operand is less than zero
catch(int c) return 0; caught an integer
{ } End of try-catch system
cout << "\nSecond Operand is less than zero" << endl; Second operand is equal to zero
cout<<”caught an integer”<<endl; caught a double
}
End of try-catch system
RE-THROWING EXCEPTION
We can make the handler(catch block) to rethrow the exception caught without processing it. In such
situations, we may simply invoke “throw” without any argument.
throw;
This causes the current exception to be thrown to the next enclosing try/catch sequence and is caught
by a catch statement of that try/catch block.
#include<iostream>
using namespace std; int main()
void Calculate(double a,double b) {
{ cout<<”Inside the main block”<<endl;
cout<<”Inside the function”<<endl; try
try {
{ calculate(10.5,2.0);
if(b==0) calculate(10.5,0.0);
throw b; //throwing double }
else catch(double)
cout<<"\nThe result is:"<<a/b<<endl; {
} cout<<"\nInside the Catch block if the main() function";
catch(double) //catch a double cout<<"\nException due to 0"<<endl;
{ }
cout<<"\nCaught double value inside the catch block of the function"; return 0;
throw; //rethrowing double }
}
}
RE-THROWING EXCEPTION
Output:
Inside the main block
Inside the function
The result is 5.25
catch(...)
{
//Statements for processing
//All exceptions
}
CATCHING ALL EXCEPTION
#include<iostream>
using namespace std;
int main()
void test(int x)
{
{
cout<<”Testing generic catch”<<endl;
try
test(-1);
{
test(0);
if(x == 0)
throw x;
test(1); Output:
return 0;
if(x == -1)
}
Testing generic
catch
throw ‘x’;
if(x == 1)
caught an exception
throw 1.0; caught an exception
}
catch(...) //catch all
caught an exception
{
cout<<”caught an exception”;
}
}
NOTE:
It may be a good idea to use the catch(...) as a default statement along with other catch handlers so that it
can catch all those exceptions which are not handled explicitly.
Remember, catch(..) should always be placed last in the list of catch handlers. Placing it before other
catch blocks would prevent those blocks from catching exceptions.
EXCEPTION WITH ARGUMENTS
There may be situations where we need more information about the cause of exception. Let us
consider there may be more than one function that throws the same exception in a program. It
would be nice if we know which function threw the exception and the cause to throw an
exception. This can be accomplished by defining the object in the exception handler. This
means, adding data members to the exception class which can be retrieved by the exception
handler to know the cause. While throwing, a throw statement throws an exception class object
with some initial value, which is used by the exception handler.
EXCEPTION WITH ARGUMENTS
#include<iostream> void calculate()
using namespace std; {
class argument if(b == 0)
{ throw argument("Divided by Zero.");
int a, b; if(b < 0)
public: throw argument("Divided by Negative number");
string msg; cout << "Quotient = " << a/b << endl;
argument() { }
a= b= 0; };
}
argument(string name) int main()
{ {
msg = name; argument A1;
} A1.input();
void input() try {
{ A1.calculate();
cout << "Enter the value of a and b : "; }
cin >> a >> b; catch(argument A)
} {
cout << "Exception : " << A.msg << endl;
}
return 0;
}
EXCEPTION SPECIFICATION FOR FUNCTION
It is possible to restrict a function to throw only certain specified exceptions. This is achieved by
adding a throw list clause to the function definition.
The general form of using an exception specification is:
return_type function_name(arg_list) throw(type list)
{
//body of function
}
The type list specifies the type of exceptions that may be thrown. Throwing any other type of
exception will cause abnormal program termination.
If we wish to prevent a function from throwing any exception, we may do so bymaking the type
list empty i.e.
return_type function_name(arg_list) throw()
{
//function body
}
EXCEPTION SPECIFICATION FOR FUNCTION
int main()
#include<iostream> {
using namespace std; int c,d;
cout<<"\nEnter the value of c and d:";
void calculate(int a,int b) throw(int) cin>>c>>d;
{ try {
if(b==0) calculate(c,d); Output1:
throw 2.0; }
if(b<0) catch(double)
Enter the value of c and d:
throw 1; { 5
cout<<"\nQuotation is :"<<a/b; cout<<"\nException as Second operand is -ve"; 0
} }
Output2:
return 0; Enter the value of c and d:
} 5
-2
In first run, the calculate function is throwing double value which is not specified in the throw list. Hence
the program terminates.
In second run, the calculate function is throwing an int exception, but there is no catch handler for int. So
the program terminates.
HANDLING UNCAUGHT AND UNEXPECTED EXCEPTIONS
Handling uncaught exceptions:
If the exception is thrown and no exception handler is found(i.e. the exception is not caught) -
the program calls the terminate() function. We can specify our own termination function with
the set_terminate() function.
int main()
{
#include<iostream> set_terminate(test_handler);
using namespace std; try
void test_handler() {
{ cout<<”Inside try block.”<<endl; Output:
cout<<”Program is terminated….”; throw 10; Inside try block
} }
Program is terminated....
catch(char c)
{
cout<<”caught exception”;
}
return 0;
}
Here, int is thrown but there is no catch handler to catch the int exception. So, the program is
terminates calling the test_handler() function.
HANDLING UNCAUGHT AND UNEXPECTED EXCEPTIONS
Handling unexpected exceptions:
Similar to uncatch exception, When a function attempts to throw an exception that is not in the
throw list, unexpected() function is invoked. Like in terminate() function, we can specify the
function that is called by the unexpected() with the help of set_unexpected() function.
#include<iostream> int main()
using namespace std; {
void test_unexpected() set_unexpected(test_unexpected);
{ try
cout<<”Program terminated due to unexpected exception”<<endl; { Output:
} calculate(2,-7);
void calculate( int a, int b) throw(int) } Program terminated due
{ catch(int c) to unexpected exception
if(b == 0) {
throw ‘A’; cout<<”Integer Exception”<<endl;
if(b<0) }
throw 1.0; //double value is thrown which is not allowed catch(double d)
cout<<”Result is :”<<a/b<<endl; {
} cout<<”Double Exception”<<endl;
}
return 0;
}
Here, calculate() function is trying to throw a double value which is not included in the throw
list, So, an unexpected exception occurs which calls the test_unexpected().
THANK YOU