You are on page 1of 32

Object Oriented Programming

(CS2133)
By

Dr. Muhammad Azhar Iqbal

Department of Computer Science,


Mohammad Ali Jinnah University, Islamabad
Fall Semester, 2013
Exception Handling
Objectives

 To understand exceptions and exception handling


 To know how to throw an exception and how to catch it
 To understand the advantages of using exception handling
 To create exceptions using C++ standard exception classes
 To create custom exception classes
 To catch multiple exceptions
 To explain how an exception is propagated
 To rethrow exceptions in a catch block
Exception and Exception Handling

 Exceptions
 Indicate problems that occur during a program’s execution
 Occur infrequently

 Exception handling
 Can resolve exceptions
 Allow a program to continue executing or
 Notify the user of the problem and
 Terminate the program in a controlled manner

 Makes programs robust and fault-tolerant


Exception Handling

 Exception handling is the process of responding to the occurr


ence anomalous or exceptional situations – requiring special
processing – often changing the normal flow of program exe
cution.

 Exception handling is a mechanism that separates code that d


etects and handles exceptional circumstances from the rest of
your program.

 Note that an exceptional circumstance is not necessarily an er


ror.
Exception Handling

 When a function detects an exceptional situation, programmer can repres


ent this with an object. This object is called an exception object.

 In order to deal with the exceptional situation you throw the exception. Th
is passes control, as well as the exception, to a designated block of code in
a direct or indirect caller of the function that threw the exception. This blo
ck of code is called a handler.

 In a handler, programmer can specify the types of exceptions that it may p


rocess. The C++ run time, together with the generated code, will pass cont
rol to the first appropriate handler that is able to process the exception thr
own. When this happens, an exception is caught. A handler may rethrow a
n exception so it can be caught by another handler.
Exception – An Example

void main()
{
int num1, num2;
cout<<“Enter two integers:”;

cin>>num1>>num2;

cout<<num1<<“ / ”<<num2<< “ is “<< (num1/num2)<<endl;

}
Exception – An Example

void main()
{
int num1, num2;
cout<<“Enter two integers:”;

cin>>num1>>num2;

if(num2 != 0)
cout<<num1<<“ / ”<<num2<< “ is “<< (num1/num2)<<endl;
else
cout<<“Divisor can not be zero \n”;
}
Exception – An Example
void main()
{
int num1, num2;
cout<<“Enter two integers:”;
cin>>num1>>num2;

try{
if(num2 == 0)
throw num1;

cout<<num1<<“ / ”<<num2<< “ is “<< (num1/num2)<<endl;


cout<<“Calculation completed\n”;

}catch(int e){
cout<<“Exception: an integer “<<e<<“cannot be divided by zero”<<endl;
}
Template for try-throw-catch

try
{
Code to try;
Throw an exception with a throw statement or from function if necessary;
More code to try;
}
catch (type e)
{
Code to process the exception;
}
Omitting catch block parameter
 If you are not interested in the contents of an exception object, th
e catch block parameter may be omitted. For example, the followi
ng catch block is legal.

try
{
// ...
}
catch (type)
{
cout << "Error occurred " << endl;
}
Exception Handling Advantages
 Exception handling is the process of responding to the occu
rrence anomalous or exceptional situations – requiring spec
ial processing – often changing the normal flow of program
execution.

 Exception handling is a mechanism that separates code that


detects and handles exceptional circumstances from the res
t of your program.

 Note that an exceptional circumstance is not necessarily an


error.
Exception Handling Advantages
int Quotient(int number1, int number2){
if(num2 == 0)
throw num1;
return num1/num2;
}
void main(){
int num1, num2;
cout<<“Enter two integers:”;
cin>>num1>>num2;
try{
int result = Quotient(num1,num2);
cout<<num1<<“/”<<num2<<“ is “<<result;
}catch(int e){
cout<<“Divide Zero Exception from function:”<<e;
}
cout<<“Execution continues … “<<endl;
}
Exception Classes
 C++ provides a number of predefined classes that can be used for creating
exception objects.

overflow_error
runtime_error
underflow_error
bad_alloc

bad_cast
exception
bad_type_id

bad_exception
invalid_argument

logic_error length_error

out_of_range
Use of standard Exception classes – example
void main()
{
try{
for(int i=1; i<=100; i++)
{
new int[7000000];
cout<<i<<“ arrays have been created”;
}
}
catch(bad_alloc &e)
{
cout<<“Exception: “<<e.what()<<endl;
}
}
Use of standard Exception classes – example

void main()
{
try{
Rectangle rec(3, 4);
Circle &c = dynamic_cast<Circle &>rec;
}
catch(bad_cast &e)
{
cout<<“Exception: “<<e.what()<<endl;
}
}
Use of standard Exception classes – example
class A {
virtual void Member() = 0;
};

void main ()
{
try{
A *a = 0;
cout << typeid(*a).name();
}
catch (bad_typeid& bt){
cerr << bt.what() << endl;
}
}
Exception Handling with Classes
Exception Handling with Classes
class AClass
{
public:
class AnError{ };
void Func()
{
throw AnError();
}
};

void main()
{
try{
AClass obj1;
obj1.Func();
}catch(AClass::AnError){
cout<<"Error Occurred\n";
}
}
Exception Handling with classes
const int MAX = 3; //stack holds 3 integers void main()
class Stack{ {
private: Stack s1;
int st[MAX]; //array of integers try
int top; //index of top of stack {
public: s1.push(11);
class Range //exception class for Stack s1.push(22);
{ }; s1.push(33);
Stack(){ top = -1; } // s1.push(44);
void push(int var){ cout << "1: " << s1.pop() << endl;
if(top >= MAX-1) //if stack full, cout << "2: " << s1.pop() << endl;
throw Range(); //throw exception cout << "3: " << s1.pop() << endl;
st[++top] = var; //put number on stack cout << "4: " << s1.pop() << endl;
} }
int pop(){ catch(Stack::Range)
if(top < 0) //if stack empty, { cout << "Exception: Stack Full/Empty\n"; }
throw Range(); //throw exception
return st[top--]; //take number off stack cout << "Arrive here after catch";
} }
};
Exception Handling with classes
const int MAX = 3; //stack holds 3 integers void main()
class Stack{ {
private: Stack s1;
int st[MAX]; //array of integers try
int top; //index of top of stack {
public: s1.push(11);
class Full { }; s1.push(22);
class Empty{ }; s1.push(33);
Stack(){ top = -1; } // s1.push(44); //oops: stack full
void push(int var){ cout << "1: " << s1.pop() << endl;
if(top >= MAX-1) //if stack full, cout << "2: " << s1.pop() << endl;
throw Full(); //throw exception cout << "3: " << s1.pop() << endl;
st[++top] = var; //put number on stack cout << "4: " << s1.pop() << endl;
} }
int pop(){ catch(Stack::Full)
if(top < 0) //if stack empty, { cout << "Exception: Stack Full"; }
throw Empty(); //throw exception catch(Stack::Empty)
return st[top--]; //take number off stack { cout << "Exception: Stack Empty"; }
} }
};
Exception Handling with classes

class AClass void main()


{ {
public:
class AnError{ try{
public: AClass obj1;
void what() obj1.Func();
{ }catch(AClass::AnError e)
cout<<"Exception related to AnError Class";
} {
}; e.what();
void Func() }
{ }
throw AnError();
}
};
Multiple Catches

 Most of time, a try block should run without ex


ceptions. But occasionally, it may throw an exc
eption. The exception can be of differing types.

 One catch block can catch only one type of exc


eption. C++ allows you to add multiple catch bl
ocks after a single try block in order to catch m
ultiple types of exceptions.
catch block base class

 Various exception classes can be derived from a comm


on base class.

 If a catch block catches exception objects of a base cla


ss, it can catch all the exception objects of the derived
classes of that base class.
order of exception handlers
 The order in which exceptions are specified in catch blocks is imp
ortant. A catch block for a base class type should appear after a
catch block for a derived class type. Otherwise, the exception of
a derived class is always caught by the catch block for the base c
lass.

try try
{ {
... ...
} }
catch (exception &ex) catch (logic_error &ex)
{ {
... ...
} }
catch (logic_error &ex) catch (exception &ex)
{ {
... ...
} }

(a) Wrong order (b) Correct order


Order of Exception Handlers

class AClass void main()


{ {
public: try{
class AnError{ AClass obj1;
public: obj1.Func();
void what(){ }
cout<<"AnError Exception"; catch(...)
} {
}; cout<<"Exception Generated";
void Func() }
{ catch(AClass::AnError e)
throw AnError(); {
} e.what();
}; }
};
Order of Exception Handlers

class AClass void main()


{ {
public: try{
class AnError{ AClass obj1;
public: obj1.Func();
void what(){ }
cout<<"AnError Exception"; catch(AClass::AnError e)
} {
}; e.what();
void Func() }
{ catch(...)
throw AnError(); {
} cout<<"Exception Generated";
}; }
};
Exception Propagation
You now know how to declare an exception and how to throw an e
xception. When an exception is thrown, it can be caught and handl
ed in a try-catch block, as follows:
int main() { function1 function2
... { {
... ... An exception
try
try try is thrown in
{
... { { function3
invoke function1; ... ...
statement1; invoke function2; invoke function3;
} statement3; statement5;
} }
catch (Exception1 &ex1) catch (Exception2 &ex2)
{ catch (Exception3 &ex3)
Process ex1; { {
} Process ex2; Process ex3;
statement2; } }
} statement4; statement6;
} }

Call Stack
function3

function2 function2

function1 function1 function1

main main main main


Rethrowing Exceptions
C++ allows an exception handler to rethrow the exception if the ha
ndler cannot process the exception or the handler simply wants to
let its caller be notified of the exception. The syntax may look like t
his:
try
{
statements;
}
catch (TheException &ex)
{
perform operations before exits;
throw;
}
When to Use Exceptions
 In general, common exceptions that may occur in multiple cla
sses in a project are candidates for exception classes. Simple e
rrors that may occur in individual functions are best handled l
ocally without throwing exceptions.

 Exception handling is for dealing with unexpected error condi


tions. Do not use a try-catch block to deal with simple, expect
ed situations. Which situations are exceptional and which are
expected is sometimes difficult to decide.

 The point is not to abuse exception handling as a way to deal


with a simple logic test.
General Paradigm for Exception
A general paradigm for exception handling is that you declare to
throw an exception in a function as shown in (a), and call the fu
nction in a try-catch block as shown in (b).

returnType function1(parameterList) returnType function2(parameterList)


throw (exceptionList) {
{ try
... {
if (an exception condition) ...
throw AnException(arguments); funciton1(arguments);
... ...
} }
catch (AnException &ex)
{
Handler;
}
...
}

(a) (b)
Exercise

 Define an Inner class named MyException having a function Why


() with display statement “Because of Exception”. Throw an excep
tion of inner class type in a function named MyFunction() in the
outer class named MyClass. Test this type of exception handling i
n the main() function.

 Define a custom exception class named SafeArray and let the pus
h function of this class to throw BoundException (your own defin
ed exception class) if the array is already full. Write a test progra
m with a try-catch block to handle this type of exception.

You might also like