0% found this document useful (0 votes)
49 views

Exception Handling

The document provides an overview of exceptions in C++. It discusses why exceptions are needed to handle runtime errors, describes the syntax and mechanism of exceptions using try, throw, and catch keywords. It provides an example of a simple exception thrown by a stack class when the stack is full or empty, and how the exception is caught and handled. It also discusses how multiple exceptions can be thrown from a class.

Uploaded by

Muhammad Waqas
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views

Exception Handling

The document provides an overview of exceptions in C++. It discusses why exceptions are needed to handle runtime errors, describes the syntax and mechanism of exceptions using try, throw, and catch keywords. It provides an example of a simple exception thrown by a stack class when the stack is full or empty, and how the exception is caught and handled. It also discusses how multiple exceptions can be thrown from a class.

Uploaded by

Muhammad Waqas
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 38

Programming Language-II

Lecture # 20
Outline
• Exceptions

• Why Do We Need Exceptions?

• Exception Syntax and Mechanism

• A Simple Exception Example

• Multiple Exceptions

• Exceptions with Arguments

• Exception Notes
2
Exceptions
• Exceptions provide a systematic, object-
oriented approach to handling run-time errors
generated by C++ classes.
• Exceptions are errors that occur at runtime.
• They are caused by a wide-variety
exceptional circumstance, such as:
– running out of memory
– not being able to open a file
– trying to initialize an object to an impossible value
3 – using an out-of-bounds array index
Why Do We Need Exceptions?
• Why do we need a new mechanism to handle
errors?
• In C/C++ programs, an error is often signaled
by returning a particular value from the
function in which it occurred.
• Example: disk file functions often return null
or 0 to signal an error.
• Each time we call these functions, we check
4
the return value.
Why Do We Need Exceptions?
if(somefunc() == ERROR_RETURN_VALUE)
//handle the error or call error-handler function
else
//proceed normally
if(anotherfunc() == null)
//handle the error or call error-handler function
else
//proceed normally
if(thirdfunc() == 0)
//handle the error or call error-handler function
else
5
//proceed normally
Why Do We Need Exceptions?
• One problem with this approach is that every
single call to such a function must be
examined by the program.
• Surrounding each function call with an
if…else statement, and adding statements to
handle the error (or call an error handler
routine), requires a lot of code and makes the
listing complex and hard to read.
• The problem become more complex when
classes are used, since errors may take place
6 without a function being explicitly called.
Why Do We Need Exceptions?
• Example: suppose an application defines

objects of a class

– SomeClass obj1, obj2, obj3;

• How will the application find out if an error

occurred in the class constructor?

– The constructor is called implicitly, so there is no

return value to be checked.


7
Exception Syntax
• Imagine an application that creates and
interacts with objects of a certain class.
• Ordinarily the application’s call to the class
member functions cause no problems.
• Sometimes, however the application makes a
mistake, causing an error to be detected in a
member function.
• This member function then informs the
application that an error has occurred.
• When exceptions are used, this is called
throwing an exception.
8
Exception Syntax
• In the application we add a separate section
of code to handle the error.
• This code is called an exception handler or
catch block; it catches the exception thrown
by the member function.
• Any code in the application that uses objects
of the class is enclosed in a try block.
• Errors generated in the try block will be
caught in the catch block.
• Code that does not interact with a class does
9
not need to be in a try block.
Exception Mechanism
Application
Class
Does not
interact with
class
good call

normal return
good call Code that
interacts with
normal return
class
bad call
Error
Catch block
Displays error
message, etc.

10
Exception Syntax
• The exception mechanism uses 3 new C++
keywords:
– throw

– catch

– try

• Also we need to create a new kind of entity


called an exception class.

11
Exception Syntax
class AClass
{
public:
class AnError //exception class
{
};
void func()
{
if(/*error condition*/)
throw AnError(); //throw exception
}
12
};
Exception Syntax
int main()
{
try
{
AClass obj1;
obj1.func();
}
catch(AClass::AnError)
{
//tell user about error, etc.
}
return 0;
}
13
Exception Syntax
• An exception class, AnError, is specified in the public
part of AClass.
• In AClass’s member functions we check for errors.
• If we find one, we throw an exception, using the
keyword throw followed by the constructor of the
class.
– throw AnError(); // followed by constructor for AnError class.
• In the main part of the program we enclose any
statements that interact with AClass member in a try
block.
• If any of these statements causes an error to be
detected in an AClass member function, an exception
will be thrown and control will go to the catch block
that immediately follows the try block.
14
A Simple Exception Example
class Stack void push(int var)
{ {
private: if(top>=2)
int data[3]; throw Range();
int top; data[++top]=var;
public: }
class Range int pop()
//exception class for {
stack if(top<0)
{/*empty class body*/}; throw Range();
Stack() { return data[top--];
top=-1; }
} };
15
A Simple Exception Example
#include"stack.h" cout<<s1.pop()<<endl;
#include<iostream> cout<<s1.pop()<<endl;
using namespace std; cout<<s1.pop()<<endl;
void main() //stack empty
{
}
Stack s1;
catch(Stack::Range)
try
{ {
s1.push(11); cout<<"Exception: stack
s1.push(22); full or empty"<<endl;
s1.push(33); }
//s1.push(44);//stack full cout<<"after catch"<<endl;
cout<<s1.pop()<<endl; }
16
Specifying the Exception Class
• The program first specifies an exception class
within the stack class.
– class Range //exception class for stack
– {/*empty class body*/};

• The body of this class is empty, so objects of


this class have no data and no member
functions.
• The class body need not always be empty.
17
Throwing an Exception
• The member functions of the stack class
checks for possible range violations using if
statement, and throws an exception if they
occur.
• Example: throw Range();
• The Range() invokes the implicit constructor
for the Range class, which creates an object
of this class.
• The throw part of the statement transfers
program control to the exception handler.
18
The try Block
• All the statements in the main() that might
cause this exception are enclosed in braces
and preceded by try keyword.
try
{
//code that operates on objects that might cause an
exception
}
• Not all the code in the program needs to be in
the try block, just the code that interacts with
the Stack class.
19 • There can be many try blocks in a program.
Exception Handler (Catch Block)
• The code that handles an exception is enclosed in
braces, preceded by the catch keyword, with the
exception class name in parentheses.
• The exception class name must include the class in
which it is called.
• Example: Stack::Range
catch(Stack::Range)
{/*code that handles the exception*/}
• This construction is called the exception handler.
• It must immediately follow the try block.
• Control falls through the bottom of the exception
handler; so we can continue processing at that point.
Or the exception handler may transfer control else
20
where, or terminate the program.
Sequence of Events
• Sequence of events when an exception
occurs.
1. Code is executing normally outside a try
block.
2. Control enters the try block.
3. A statement in the try block causes an error
in a member function.
4. The member function throws an exception.
5. Control transfers to the exception handler
(catch block) following the try block.
21
Multiple Exceptions
• We can design a class to throw as many
exceptions as we want.

• Example:

– We can modify the stack program so that it


throws separate exceptions for:
• attempting to push data on a full stack and

• attempting to pop data from an empty stack.

22
Multiple Exceptions
class Stack void push(int var)
{ {
private: if(top>=2)
int data[3]; throw Full();
data[++top]=var;
int top;
}
public:
int pop()
class Full {
{/*empty class body*/}; if(top<0)
class Empty throw Empty();
{/*empty class body*/}; return data[top--];
Stack() }
{top=-1;} };
23
Multiple Exceptions
#include<iostream> cout<<s1.pop()<<endl;//stac
k empty
using namespace std;
}
void main() { catch(Stack::Full)
Stack s1; {
try { cout<<"Exception: stack
full"<<endl;
s1.push(11);
}
s1.push(22);
catch(Stack::Empty)
s1.push(33); {
//s1.push(44);//stack full cout<<"Exception: stack
cout<<s1.pop()<<endl; empty"<<endl;
}
cout<<s1.pop()<<endl;
cout<<"after catch"<<endl;
cout<<s1.pop()<<endl; }
24
Exceptions with Arguments
• Throwing an exception involves not only
transferring control to the handler, but also
creating an object of the exception class by
calling its constructor.
• We can use this object for providing more
information about what caused an exception.
– If we add data members to the exception class, we
can initialize them when we create the object.
– The exception handler can then retrieve the data
from the object when it catches the exception.
25
Exceptions with Arguments
#include<iostream> InchesEx(string or, float in)
#include<string> {origin=or; ivalue=in;}
using namespace std; };
class Distance Distance():feet(0),inches(0.0){}
{ Distance(int ft,float in)
private: {
int feet; if(in>=12.0)
float inches; throw InchesEx("2-arg
public: constructor",in);
class InchesEx feet=ft;
{ inches=in;
public: }
string origin; //for name void readDist();
of function void showDist()const;
float ivalue; //for faulty };
inches value
26
Exceptions with Arguments
#include"distance.h" void Distance::
void Distance::readDist() showDist() const
{ {
cout<<"\nEnter feet: "; cout<<feet<<endl
cin>>feet; <<inches<<endl;
cout<<"\nEnter inches: "; }
cin>>inches;
if(inches>=12.0)
throw
InchesEx("readDist
function",inches);
}

27
Exceptions with Arguments
#include"distance.h"
void main() {
try {
Distance dist1(17,3.5);
Distance dist2;
dist2.readDist();
dist1.showDist();
dist2.showDist();
}
catch(Distance::InchesEx ix)
{
cout<<"Initialization error in: "<<ix.origin<<endl
<<"Inches value is too large: "<<ix.ivalue<<endl;
}
28 }
Exceptions with Arguments
• There are three parts to the operation of
passing data when throwing an exception:
– Specifying the data members and a constructor for
the exception class.

– Initializing this constructor when we throw an


exception.

– Accessing the object’s data when we catch the


exception.
29
Specifying Data in an Exception Class
• It is convenient to make data in an exception
class public so it can be accessed directly by
the catch block.
• Example
class InchesEx
{
public:
string origin;//for name of function
float ivalue;//for faulty inches value
InchesEx(string or, float in)
{origin=or; ivalue=in;}
30 };
Initializing an Exception Object
• How do we initialize the data when we throw
an exception?

• Example:
– throw InchesEx("2-arg constructor",in);

– throw InchesEx("readDist function",inches);

31
Extracting Data from the Exception Object

• How do we extract this data when we catch


the exception?
• In the catch block we declared ix as the name
of the exception object we’re catching.
• Using this object, we can refer to its data in
the usual way, using the dot operator.
• Example
catch(Distance::InchesEx ix)
{/*access ix.origin and ix.ivalue directly*/
32
The bad_alloc Class
• The most commonly used built-in exception
class is bad_alloc.

• This is thrown if an error occurs when


attempting to allocate memory with new.

• If we setup the appropriate try and catch


blocks, we can make use of bad_alloc with
very little effort.

33
The bad_alloc Class
#include<iostream>
using namespace std;
void main() {
const unsigned long SIZE=100000;
char *ptr;
try {
ptr=new char[SIZE];
}
catch(bad_alloc) {
cout<<"bad_alloc exception: can't allocate memory"<<endl;
return;
}
delete[] ptr;
cout<<"memory use is successful"<<endl;
34
}
Exception Notes
• Function Nesting
– The statement that causes an exception
need not to be located directly in the try
block
• it can also be in a function that is called by a
statement in the try block
• or in a function called by a function that is called
by a statement in the try block, and so on.
– We only need to install a try block on the
program’s upper level.
35
Exception Notes
• Exceptions should not be used for every kind
of error.
• They impose a certain overhead in terms of
program size and in time.
• Example:
– Exceptions should not be used for for user input
errors.
– Instead the program should use normal decisions
and loops to check the user’s input and request the
user to try again if necessary.
36
Exception Notes
• Destructor Called Automatically
– The exception mechanism is surprisingly
sophisticated.
– When an exception is thrown, a destructor
is called automatically for any object that
was created by the code up to that point in
the try block.
– The exception mechanism guarantees that
the code in the try block will have been
reset, at least as far as the existence of
objects is concerned.
37
Exception Notes
• Handling Exceptions
– When we catch an exception, we get a
chance to either continue program
execution or terminate the program.
– Exception mechanism gives us a chance to
• indicate the source of error to the user
• perform any necessary clean-up
• or continue program execution, again from the
start of the try block, after fixing the error
38

You might also like