UNIT 5: EXCEPTION HANDLING
FUNDAMENTALS OF EXCEPTION HANDLING
• An exception is a problem arises during the execution of a program. A C++ exception is a response to an
exceptional circumstance that arises while a program is running, such as an attempt to divide by zero.
• Exceptions provide a way to transfer control from one part of a program to another. C++ exception
handling is built upon three keywords: try, catch, and throw.
• throw : A program throws an exception when a problem shows up. This is done using a throw keyword.
• catch : A program catches an exception with an exception handler at the place in a program where you
want to handle the problem. The catch keyword indicates the catching of an exception.
• try : A try block identifies a block of code for which particular exceptions will be activated. It's followed
by one or more catch blocks.
• Assuming a block will raise an exception, a method catches an exception using a combination of the try
and catch keywords. Code within a try/catch block is referred to as protected code.
• SYNTAX:
try {
// protected code
}
catch( ExceptionName e1)
{
// catch block
}
catch( ExceptionName e2 )
{
// catch block
}
catch( ExceptionName eN )
{
// catch block
}
Throwing Exception:
- Exception can be thrown anywhere within the code block using throw statement. The operand of the
throw statement determines a type for the exception and can be any expression and the type of the
result of the expression determines the type of exception thrown.
- EXAMPLE:
double division(int a, int b)
{
if(b==0)
{
throw "Division by zero condition";
}
return (a/b);
}
Catching Exception:
- The catch block following the try block catches any exception. You can specify what type of exception
you want to catch and this is determined by the exception declaration that appears in the parentheses
following the keyword catch:
OOPS UNIT 5 Page 1
following the keyword catch:
- EXAMPLE:
try
{
//protected code
}
catch(ExceptionName e)
{
//code to handle ExceptionName exception
}
- Here code will catch an exception of ExpceptionName type.
- Catch block can handle any type if
try
{
//protected code
}
catch(…)
{
//code to handle any exception
}
Other Error handling techniques
Sr. Exception and Description
No
1. std :: exception
An exception and parent class of all the standard C++ exceptions.
2. std :: bad_alloc
This can be thrown by new.
OOPS UNIT 5 Page 2
This can be thrown by new.
3. std :: bad_cast
This can be thrown by dynamic_cast.
4. std :: bad_exception
This is useful device to handle unexpected exceptions in a C++ program.
5. std :: bad_typeid
This can be thrown by typeid.
6. std :: logic_error
An exception that theoretically can be detected by reading the code.
7. std :: domain_error
This is an exception thrown when a mathematically invalid domain is used.
8. std :: invalid_argument
This is thrown due to invalid arguments.
9. std :: length_error
This is thrown when a too big std :: string is created.
10. std :: out_of_range
This can be thrown by the 'at' method, for example a std :: vector and std :: bitset<> :: operator[]().
11. std :: runtime_error
An exception that theoretically cannot be detected by reading the code.
12. std :: overflow_error
This is thrown if a mathematical overflow occurs.
13. std :: range_error
This is occurred when you try to store a value which is out of range.
14. std :: underflow_error
This is thrown if a mathematical underflow occurs.
Simple Exception Handling - Divide by Zero
#include<iostream>
using namespace std;
int main()
{
int a = 50;
int b = 0;
double c = 0;
try
{
if(b == 0)
{
throw(1);
}
c=a/b;
cout << "\n Division is " << c;
}
catch (int i)
{
OOPS UNIT 5 Page 3
{
cout << "Divide by zero error!";
}
return 0;
}
Multiple Catching
• Whenever exception happens exception handler searches for appropriate handler and catches the
exception. One try can have multiple catch blocks but many try block cannot have one catch block.
• E.g.
#include<iostream>
using namespace std;
int main()
{
int a;
cout << "\n Example of multiple exception";
cout << "\n Enter the no ";
cin>>a;
try
{
if(a == 1)
{
throw 10;
}
if(a == 2)
{
throw float (20.4);
}
if(a == 3)
{
throw 'x';
}
cout << "\n Exception does not occurs";
}
catch(int a)
{
cout << "\n This is first exception and value is " << a;
}
catch(float a)
{
cout << "\n This is first exception and value is " << a;
}
catch(char a)
{
cout << "\n This is first exception and value is " << a;
}
return 0;
}
OOPS UNIT 5 Page 4
}
Re-throwing an Exception
• Exception handler may decide to rethrow exception without handling it.
• We use throw keyword. No argument to be passed.
• throw statement causes current exception to be thrown to next try catch clause. Exception is caught by
next enclosing try ... catch blocks.
• Example:
#include<iostream>
using namespace std;
int main()
{
cout << "\n Example of Rethrowing exception";
try
{
try
{
throw 10;
}
catch(int a)
{
cout<< "Inner try catch";
throw;
}
}
catch(int a)
{
out<< "Outer try catch"<<a;
}
return 0;
}
• Example 2:
#include<iostream>
using namespace std;
void test()
{
try
{
throw "\n Try catch example";
}
catch (const char*)
{
cout << "\n Inner try ... catch block";
throw; //we are rethrowing the exception to outer try ... catch block.
}
}
int main()
{
OOPS UNIT 5 Page 5
{
cout << "\n Rethrowing exception example";
try
{
test();
}
catch (const char*)
{
cout << "\n Outer try catch";
}
return 0;
}
OUTPUT:
Rethrowing exception example
Inner try ... catch block
Outer try catch
Exception Specifications
• A specific exception can be thrown and only this will be executed.
• It is possible by adding throw list clause during function definition.
• If when throw anything other than defined list program terminates.
• Syntax:
Return_type function_name(arguments) throw(type list)
{
//body of the function.
}
• E.g.
#include<iostream>
using namespace std;
void example (int a) throw (int,double)
{
if(a==0)
throw 'a';
else if(a==1)
throw a;
else if(a==-1)
throw 231.30;
}
int main()
{
try
{
cout << "testing throw restrictions\n";
cout << "x == 10\n";
example(10);
cout << "x == 1\n";
example(1);
cout << "x ==- 1 \n";
OOPS UNIT 5 Page 6
cout << "x ==- 1 \n";
example(-1);
cout << "x == 2\n";
example(2);
}
catch(char c)
{
cout << "caught a character \n";
}
catch(int m)
{
cout << "caught a integer \n";
}
catch(double d)
{
cout << "caught a double \n";
}
return 0;
}
OUTPUT:
testing throw restrictions
x == 10
x == 1
caught a integer
User Defined Exception
• User Defined Exception or custom exception is creating your own exception class and throws that
exception using 'throw' keyword. This can be done by extending the class exception.
• E.g.
#include<iostream>
#include<exception>
using namespace std;
class Divide_by_zero_Exception: public exception
{
public:
const char* what() const throw()
{
return "Divide by zero Exception";
}
};
int main()
{
try
{
int a, b;
cout << "Enter two number";
cin>>a>>b;
if(b==0)
OOPS UNIT 5 Page 7
if(b==0)
{
Divide_by_zero_Exception d;
throw d;
}
else
{
cout<<a/b;
}
}
catch(exception& e)
{
cout <<e.what();
}
}
Processing Unexpected Exceptions
• Even after handling exceptions, there may be unexpected exceptions. Unexpected exception terminates
the program.
• It is hard to write exception safe code. Always use exception when there is really need.
• Consider a case where function is for addition of two numbers. Then it is unnecessary to handle
exception in this situation.
• The process of removing function from function stack during runtime is called as stack unwinding.
• In C++, when an exception occurs, the function call stack is linearly searched for the exception handler,
and all the entries before the function with exception handler are removed from the function call stack.
So exception handling involves Stack Unwinding if exception is not handled in same function.
• E.g.
#include<iostream>
using namespace std;
void fun1() throw (int)
{
cout << "\n This is start of fun1()";
throw 235;
cout << "\n This is end of fun1()";
}
void fun2() throw (int)
{
cout << "\n This is start of fun2()";
fun1();
cout << "\n This is end of fun2()";
}
void fun3()
{
cout << "\n This is start of fun3()";
try
{
fun2();
OOPS UNIT 5 Page 8
fun2();
}
catch(int a)
{
cout << "\n Exception has been Caught: " << a;
}
cout<< "\n This is end of fun3()";
}
int main()
{
fun3();
return 0;
}
OUTPUT:
This is start of fun3()
This is start of fun2()
This is start of fun1()
Exception has been Caught: 235
This is end of fun3()
Constructor, Destructor and Exception Handling
• Whenever exception is thrown control passes to catch block, destructors are called automatically for all
objects constructed since the beginning of try block which are associated with catch block.
• If exception is thrown at the time of creating object which consists of sub-objects then destructor are
only called for those sub objects which are successfully created before throwing the exception.
• A destructor for a local static object will only be called if the object was successfully constructed.
• If a destructor detects an exception and issues a throw, the exception can be caught if the caller of the
destructor was contained within a try block and an appropriate catch is coded.
• If an exception is thrown by a function called from an inner try block, but caught by an outer try block, all
objects constructed within both the outer and all inner try blocks are destroyed.
• If you throw an object with a constructor, you can construct an object that contains information relevant
to the catch expression.
• The catch block can then access information provided by the thrown object.
• Exception handling can be used in conjunction with constructors and destructors to provide resource
management that ensures that all locked resources are unlocked when an exception is thrown.
Exception and inheritance
• If both base and derived class caught exception then catch block of derived class should appear before
the base class.
• If we put base class catch block first then derived class catch block will never be reached.
#include<iostream>
using namespace std;
class parent {};
class child: public parent {};
int main()
{
child c;
OOPS UNIT 5 Page 9
child c;
try {
cout << "\n This is example of try .... catch in inheritance";
throw c;
}
catch(child c)
{
cout << "\n This is catch block for child exception";
}
catch(parent p)
{
cout << "\n This is catch block for parent exception";
}
return 0;
}
OUTPUT:
This is example of try …. catch in heritance
This is catch block for child exception
OOPS UNIT 5 Page 10