CPP09 - W1 - M10 - Exception Handling
Learning Objectives
At the end of this module, you will be able to
* Explain why do we need exception handling.
* Explain how to write C++ programs using exception handling.
* Explain how to declare and implement exception handing.
* Identify and list different exceptions.
* Apply exceptions for file handling, memory allocation and real world scenarios.
Exception Handling
Introduction
Exceptions are errors that occur at runtime. They are caused by a wide variety of exceptional circumstance, such as running out of memory, not being able to open a file, trying to initialize an object to an impossible value, or using an out-of-bounds index to a vector.
Why do we need exceptions ?
Why do we need a new mechanism to handle errors? Let’s look at how the process was handled in the past. C-language programs often signal an error by returning a particular value from the function in which it occurred. For example, disk-file functions often return NULL or 0 to signal an error. Each time you call one of these functions you check the return value:
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
//proceed normally
The 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 convoluted and hard to read.
Exception Syntax
Imagine an application that creates and interacts with objects of a certain class. Ordinarily the application’s calls 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. In the application we install a separate section of code to handle the error. This code is called an exception handler or catch block; it catches the exceptions 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 doesn’t interact with the class need not be in a try block. Below image shows the arrangement.
exceptions.jpg
The exception mechanism uses three new C++ keywords: throw, catch, and try. Also, we need to create a new kind of entity called an exception class. XSYNTAX is not a working program, but a skeleton program to show the syntax.
0.
// xsyntax.cpp
1.
// not a working program
2.
////////////////////////////////////////////////////////////////
3.
class AClass //a class
4.
{
5.
public:
6.
class AnError //exception class
7.
{
8.
};
9.
10.
void Func() //a member function
11.
{
12.
if( /* error condition */ )
13.
throw AnError(); //throw exception
14.
}
15.
};
16.
17.
////////////////////////////////////////////////////////////////
18.
19.
int main() //application
20.
{
21.
try //try block
22.
{
23.
AClass obj1; //interact with AClass objects
24.
obj1.Func(); //may cause error
25.
}
26.
catch(AClass::AnError) //exception handler
27.
{ //(catch block)
28.
//tell user about error, etc.
29.
}
30.
return 0;
31.
}
We start with a class called AClass, which represents any class in which errors might occur. 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 for the error class:
throw AnError(); //’throw’ followed by constructor for AnError class
In the main() part of the program we enclose any statements that interact with AClass 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.
A simple Exception Example
Let’s look at a working program example that uses exceptions. This example creates a stack data structure in which integer data values could be stored. The application program might attempt to push too many objects onto the stack, thus exceeding the capacity of the array, or it might try to pop too many objects off the stack, thus obtaining invalid data. In the XSTAK program we use an exception to handle these two errors.
0.
// xstak.cpp
1.
// demonstrates exceptions
2.
#include
3.
using namespace std;
4.
const int MAX = 3; //stack holds 3 integers
5.
////////////////////////////////////////////////////////////////
6.
class Stack
7.
{
8.
private:
9.
int st[MAX]; //array of integers
10.
11.
int top; //index of top of stack
12.
public:
13.
class Range //exception class for Stack
14.
{ //note: empty class body
15.
};
16.
17.
Stack() //constructor
18.
{ top = -1; }
19.
20.
void push(int var)
21.
{
22.
if(top >= MAX-1) //if stack full,
23.
throw Range(); //throw exception
24.
st[++top] = var; //put number on stack
25.
}
26.
27.
int pop()
28.
{
29.
if(top <>
3.
using namespace std;
4.
const int MAX = 3; //stack holds 3 integers
5.
////////////////////////////////////////////////////////////////
6.
class Stack
7.
{
8.
private:
9.
int st[MAX]; //stack: array of integers
10.
int top; //index of top of stack
11.
public:
12.
class Full { }; //exception class
13.
14.
class Empty { }; //exception class
15.
16.
//--------------------------------------------------------------
17.
Stack() //constructor
18.
{ top = -1; }
19.
//--------------------------------------------------------------
20.
void push(int var) //put number on stack
21.
{
22.
if(top >= MAX-1) //if stack full,
23.
throw Full(); //throw Full exception
24.
st[++top] = var;
25.
}
26.
27.
//--------------------------------------------------------------
28.
int pop() //take number off stack
29.
{
30.
if(top < 0) //if stack empty,
31. throw Empty(); //throw Empty exception
32. return st[top--];
33. }
34. };
35. ////////////////////////////////////////////////////////////////
36. int main()
37. {
38. Stack s1;
39. try
40. {
41. s1.push(11);
42. s1.push(22);
43. s1.push(33);
44. // s1.push(44); //oops: stack full
45. cout << “1: “ << s1.pop() << endl;
46. cout << “2: “ << s1.pop() << endl;
47. cout << “3: “ << s1.pop() << endl;
48. cout << “4: “ << s1.pop() << endl; //oops: stack empty
49. }
50. catch(Stack::Full)
51. {
52. cout << “Exception: Stack Full” << endl;
53. }
54. catch(Stack::Empty)
55. {
56. cout << “Exception: Stack Empty” << endl;
57. }
58. return 0;
59. }
In XSTAK2 we specify two exception classes: class Full { }; class Empty { }; The statement throw Full(); is executed if the application calls push() when the stack is already full, and throw Empty(); is executed if pop() is called when the stack is empty. A separate catch block is used for each exception: try { //code that operates on Stack objects } catch(Stack::Full) { //code to handle Full exception } catch(Stack::Empty) { //code to handle Empty exception } All the catch blocks used with a particular try block must immediately follow the try block. In this case each catch block simply prints a message: “Stack Full” or “Stack Empty”. Only one catch block is activated for a given exception. A group of catch blocks, or a catch ladder, operates a little like a switch statement, with only the appropriate section of code being executed. When an exception has been handled, control passes to the statement following all the catch blocks. (Unlike a switch statement, you don’t need to end each catch block with a break. In this way catch blocks act more like functions.) Specifing Data in an Exception Class What happens if the application needs more information about what caused an exception? For instance, in the XSTAK2 example, it might help the programmer to know what MAX elements the stack can have. It’s convenient to make the data in an exception class public so it can be accessed directly by the exception handler. Here’s the specification for the new Full exception class in XSTAK2: class Full{ //exception class public: int maxElements; //Max elements the stack can store string message; //For name of the routine Full(int max, string m){ maxElements = max; //put max in value in the object message = m; //put string in object } }; There are public variables for a string object, which will hold the name of the member function being called, and a type int, for the MAX stack elements. Initializing an Exception Object How do we initialize the data when we throw an exception? In the two-argument constructor for the Stack class we say throw Full(MAX,"STACK PUSH --> Stack is FULL"");
When the exception is thrown, the handler will display the string and MAX. The string will tell us which member function is throwing the exception, and the value of MAX. This additional data will make it easier for the programmer or user to figure out what caused the error.
Resources
Web Resources:
The declaration of Integer class is
Add Exceptions in the Dynamic Array if the Memory allocation failed.
You might try making the main() part of this exercise interactive, so the user can put values on a queue and take them off. This makes it easier to exercise the queue. Following an exception, the program should allow the user to recover from a mistake without corrupting the contents of the queue.
Learning Objectives
At the end of this module, you will be able to
* Explain why do we need exception handling.
* Explain how to write C++ programs using exception handling.
* Explain how to declare and implement exception handing.
* Identify and list different exceptions.
* Apply exceptions for file handling, memory allocation and real world scenarios.
Exception Handling
Introduction
Exceptions are errors that occur at runtime. They are caused by a wide variety of exceptional circumstance, such as running out of memory, not being able to open a file, trying to initialize an object to an impossible value, or using an out-of-bounds index to a vector.
Why do we need exceptions ?
Why do we need a new mechanism to handle errors? Let’s look at how the process was handled in the past. C-language programs often signal an error by returning a particular value from the function in which it occurred. For example, disk-file functions often return NULL or 0 to signal an error. Each time you call one of these functions you check the return value:
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
//proceed normally
The 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 convoluted and hard to read.
Exception Syntax
Imagine an application that creates and interacts with objects of a certain class. Ordinarily the application’s calls 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. In the application we install a separate section of code to handle the error. This code is called an exception handler or catch block; it catches the exceptions 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 doesn’t interact with the class need not be in a try block. Below image shows the arrangement.
exceptions.jpg
The exception mechanism uses three new C++ keywords: throw, catch, and try. Also, we need to create a new kind of entity called an exception class. XSYNTAX is not a working program, but a skeleton program to show the syntax.
0.
// xsyntax.cpp
1.
// not a working program
2.
////////////////////////////////////////////////////////////////
3.
class AClass //a class
4.
{
5.
public:
6.
class AnError //exception class
7.
{
8.
};
9.
10.
void Func() //a member function
11.
{
12.
if( /* error condition */ )
13.
throw AnError(); //throw exception
14.
}
15.
};
16.
17.
////////////////////////////////////////////////////////////////
18.
19.
int main() //application
20.
{
21.
try //try block
22.
{
23.
AClass obj1; //interact with AClass objects
24.
obj1.Func(); //may cause error
25.
}
26.
catch(AClass::AnError) //exception handler
27.
{ //(catch block)
28.
//tell user about error, etc.
29.
}
30.
return 0;
31.
}
We start with a class called AClass, which represents any class in which errors might occur. 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 for the error class:
throw AnError(); //’throw’ followed by constructor for AnError class
In the main() part of the program we enclose any statements that interact with AClass 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.
A simple Exception Example
Let’s look at a working program example that uses exceptions. This example creates a stack data structure in which integer data values could be stored. The application program might attempt to push too many objects onto the stack, thus exceeding the capacity of the array, or it might try to pop too many objects off the stack, thus obtaining invalid data. In the XSTAK program we use an exception to handle these two errors.
0.
// xstak.cpp
1.
// demonstrates exceptions
2.
#include
3.
using namespace std;
4.
const int MAX = 3; //stack holds 3 integers
5.
////////////////////////////////////////////////////////////////
6.
class Stack
7.
{
8.
private:
9.
int st[MAX]; //array of integers
10.
11.
int top; //index of top of stack
12.
public:
13.
class Range //exception class for Stack
14.
{ //note: empty class body
15.
};
16.
17.
Stack() //constructor
18.
{ top = -1; }
19.
20.
void push(int var)
21.
{
22.
if(top >= MAX-1) //if stack full,
23.
throw Range(); //throw exception
24.
st[++top] = var; //put number on stack
25.
}
26.
27.
int pop()
28.
{
29.
if(top <>
3.
using namespace std;
4.
const int MAX = 3; //stack holds 3 integers
5.
////////////////////////////////////////////////////////////////
6.
class Stack
7.
{
8.
private:
9.
int st[MAX]; //stack: array of integers
10.
int top; //index of top of stack
11.
public:
12.
class Full { }; //exception class
13.
14.
class Empty { }; //exception class
15.
16.
//--------------------------------------------------------------
17.
Stack() //constructor
18.
{ top = -1; }
19.
//--------------------------------------------------------------
20.
void push(int var) //put number on stack
21.
{
22.
if(top >= MAX-1) //if stack full,
23.
throw Full(); //throw Full exception
24.
st[++top] = var;
25.
}
26.
27.
//--------------------------------------------------------------
28.
int pop() //take number off stack
29.
{
30.
if(top < 0) //if stack empty,
31. throw Empty(); //throw Empty exception
32. return st[top--];
33. }
34. };
35. ////////////////////////////////////////////////////////////////
36. int main()
37. {
38. Stack s1;
39. try
40. {
41. s1.push(11);
42. s1.push(22);
43. s1.push(33);
44. // s1.push(44); //oops: stack full
45. cout << “1: “ << s1.pop() << endl;
46. cout << “2: “ << s1.pop() << endl;
47. cout << “3: “ << s1.pop() << endl;
48. cout << “4: “ << s1.pop() << endl; //oops: stack empty
49. }
50. catch(Stack::Full)
51. {
52. cout << “Exception: Stack Full” << endl;
53. }
54. catch(Stack::Empty)
55. {
56. cout << “Exception: Stack Empty” << endl;
57. }
58. return 0;
59. }
In XSTAK2 we specify two exception classes: class Full { }; class Empty { }; The statement throw Full(); is executed if the application calls push() when the stack is already full, and throw Empty(); is executed if pop() is called when the stack is empty. A separate catch block is used for each exception: try { //code that operates on Stack objects } catch(Stack::Full) { //code to handle Full exception } catch(Stack::Empty) { //code to handle Empty exception } All the catch blocks used with a particular try block must immediately follow the try block. In this case each catch block simply prints a message: “Stack Full” or “Stack Empty”. Only one catch block is activated for a given exception. A group of catch blocks, or a catch ladder, operates a little like a switch statement, with only the appropriate section of code being executed. When an exception has been handled, control passes to the statement following all the catch blocks. (Unlike a switch statement, you don’t need to end each catch block with a break. In this way catch blocks act more like functions.) Specifing Data in an Exception Class What happens if the application needs more information about what caused an exception? For instance, in the XSTAK2 example, it might help the programmer to know what MAX elements the stack can have. It’s convenient to make the data in an exception class public so it can be accessed directly by the exception handler. Here’s the specification for the new Full exception class in XSTAK2: class Full{ //exception class public: int maxElements; //Max elements the stack can store string message; //For name of the routine Full(int max, string m){ maxElements = max; //put max in value in the object message = m; //put string in object } }; There are public variables for a string object, which will hold the name of the member function being called, and a type int, for the MAX stack elements. Initializing an Exception Object How do we initialize the data when we throw an exception? In the two-argument constructor for the Stack class we say throw Full(MAX,"STACK PUSH --> Stack is FULL"");
When the exception is thrown, the handler will display the string and MAX. The string will tell us which member function is throwing the exception, and the value of MAX. This additional data will make it easier for the programmer or user to figure out what caused the error.
Resources
Web Resources:
- http://www.cplusplus.com/doc/tutorial/exceptions.html
- http://www.cprogramming.com/tutorial/exceptions.html
Steps to Attack the problem sets
- Step 1: Read about Exception and try the example programs
- Step 2: Go through the PPT on Exceptions and try stack program from the PPT.(you can copy paste the program)
- Step 3: Go through the additional resources given.
- Step 4: Attack the problem sets in the given order(Problem Set A and then Problem Set B ...).
- Step 5: If you are not clear with the problem sets then contact your respective mentor for clarification.
Problem Sets
Problem Set A
1. Write an interactive program which divides two Integer Wrapper(Declaration is given) Class Objects. Overload divide(/) operator. Handle cases such as division-by-zero using exceptions. Write a test program to test the Wrapper Integer class for division.The declaration of Integer class is
class Integer{ private: int value; public: Integer(int v){value=v;}; //Consturctor int getInt(); //returns the integer void setInt(int v); //set the int value to the object Integer operator/= (const Integer &); };
Name the program as: PA1_Integer.cpp
Problem Set B
1. Add exceptions to the queue template you have written in Module 9. Throw two exceptions: one if the capacity of the queue is exceeded, the other if the program tries to remove an item from an empty queue. One way to handle this is to add a new data member to the queue: a count of the number of items currently in the queue. Increment the count when you insert an item, and decrement it when you remove an item. Throw an exception if this count exceeds the capacity of the queue, or if it becomes less than 0.Add Exceptions in the Dynamic Array if the Memory allocation failed.
You might try making the main() part of this exercise interactive, so the user can put values on a queue and take them off. This makes it easier to exercise the queue. Following an exception, the program should allow the user to recover from a mistake without corrupting the contents of the queue.
Name the DynamicArray program as: PB1_DynamicArray.cpp Name the Queue program as: PB1_QueueException.cpp Name the Header as: PB1_QueueException.h
start creating posts on java..plzz need some help..
ReplyDeleteDude follow java tutorial in this blog.
Deletehttp://enjoylearningjava.blogspot.in/
You can learn basics within 2 weeks.
W1_-M1 means week1 module1 and so on to week2.
Each week has some 10 modules.
All the best.