Wrox Press C++ Tutorial
An exception can be loosely described as an event that you did not expect to occur. Error conditions that arise in your program are exceptions, but any unusual condition that arises, such as erroneous input, could also be considered as an exception. So far, we have typically handled error conditions by using an if statement to test some expression, and then executing some specific code to deal with the error. C++ also provides another, more general mechanism for handling exceptions which allows you to separate the code that deals with these conditions from the code that executes when such conditions do not arise. This mechanism uses three new keywords:
try - identifies a code block in which an exception can occurthrow - causes an exception condition to be originatedcatch - identifies a block of code in which the exception is handledWe can see how exception handling works by working through an example. Let's use a very simple context for this. Suppose we write a program to read the height of a person in inches, and then display the height in meters. Let's also suppose that we want to validate the height entered so that we won't accept any values greater than 100 inches, or less than 9 inches.
We could code this using exception handling as follows:
// Ex5_04.cpp Using exception handling
#include <iostream>
using namespace std;
int main()
{
int Height = 0;
double InchesToMeters = 0.0254;
char ch = 'y';
while(ch == 'y'||ch =='Y')
{
cout << "Enter a height in inches: ";
cin >> Height; // Read the height to be converted
try // Defines try block in which
{ // exceptions may be thrown
if(Height > 100)
throw "Height exceeds maximum"; // Exception thrown
if(Height < 9)
throw "Height below minimum"; // Exception thrown
cout << static_cast<double>(Height*InchesToMeters)
<< " meters" << endl;
cout << "Do you want to continue (y or n)?";
cin >> ch;
}
// start of catch block to catch exceptions of type char*
catch(const char* aMessage) //
{ //
cout << aMessage << endl;
}
}
return 0;
}
If you run this example, typical output will be as shown below:

The code in the try block is executed in the normal sequence. The try block serves to define where an exception can be raised. You can see from the output that when an exception is thrown, the catch block is executed, and execution continues with the statement following the catch block. When no exception is thrown, the catch block is not executed. Because the try block encloses the statement to output the converted value of Height and read a value for ch, and because these follow the throw statements, they are not executed when an exception is thrown. When a throw statement is executed, control passes immediately to the first statement in the catch block.
Exceptions can be thrown anywhere within a try block. In our example, we throw two exceptions in the throw statements that you see. The operand of the throw statements determines a type for the exception - both the exceptions thrown here are of type const char*. The operand following the throw keyword can be any expression and the type of the result of the expression determines the type of exception thrown.
Exceptions can also be thrown in functions called from within a try block and caught by a catch block following the try block. You could add a function to the previous example to demonstrate this, with the definition:
void TestThrow(void)
{
throw "An exception from within a function!";
}
If you place a call to this function after the statement reading the value for ch, this exception will be thrown and caught by the catch block on every iteration when no other exception is thrown. Don't forget the function prototype if you add the definition of TestThrow() to the end of the source code.
The catch block following the try block in our example catches any exception of type const char*. This is determined by the exception declaration that appears in parentheses following the keyword catch. You must supply at least one catch block for a try block, and the catch blocks must immediately follow the try block. A catch block will catch all exceptions (of the correct type) that occur anywhere in the code in the immediately preceding try block, including those thrown in any functions that are called directly or indirectly within the try block.
If you want to specify that a catch block is to handle any exception that is thrown in a try block, you must put an ellipsis, ..., between the parentheses enclosing the exception declaration:
catch (...)
{
// code to handle any exception
}
This catch block must appear last if you have other catch blocks defined for the try block.
You can nest try blocks one within another. With this situation, if an exception is thrown from within an inner try block which is not followed by a catch block corresponding to the type of exception thrown, the catch handlers for the outer try block will be searched. You can demonstrate this by modifying the previous example as follows:
// Ex5_05.cpp
// Nested try blocks
#include <iostream>
using namespace std;
int main()
{
int Height = 0;
double InchesToMeters = 0.0254;
char ch = 'y';
try // Outer try block
{
while(ch == 'y'||ch =='Y')
{
cout << "Enter a height in inches: ";
cin >> Height; // Read the height to be converted
try // Defines try block in which
{ // exceptions may be thrown
if(Height > 100)
// Exception thrown
throw "Height exceeds maximum";
if(Height < 9)
throw Height; // Exception thrown
cout << static_cast<double>(Height*InchesToMeters)
<< " meters" << endl;
cout << "Do you want to continue(y or n)?";
cin >> ch;
}
catch(char* aMessage) // start of catch block to catch
{ // exceptions of type char*
cout << aMessage << endl;
}
}
}
catch(int BadHeight)
{
cout << BadHeight << " inches is below minimum" << endl;
}
return 0;
}
Here, there is an extra try block enclosing the while loop and the second exception thrown in the inner try block has been changed to throw the value of Height when this value is below the minimum. If you run this version of the program, the exception of type char* is caught by the catch block for the inner try block. The exception of type int has no catch handler for exceptions of this type, so the catch handler for the outer try block is executed. In this case, the program ends immediately because the statement following the catch block is a return.