A program catches an exception with an exception handler at the place in the program where you want to handle the problem. The catch keyword indicates the catching of an exception. A handler begins with the keyword catch, followed by a type declaration (in parentheses) that indicates the type of exception to which it responds. That, in turn, is followed by a brace-enclosed block of code that indicates the actions to take. The catch keyword, along with the exception type, serves as a label that identifies the point in a program to which execution should jump when an exception is thrown. An exception handler is also called a catch block.

A try block identifies a block of code for which particular exceptions will be activated. It’s followed by one or more catch blocks. The try block itself is indicated by the keyword try, followed by a brace-enclosed block of code indicating the code for which exceptions will be noticed.

The easiest way to see how these three elements fit together is to look at a short example, such as the one in Listing 15.9.

Listing 15.9. error3.cpp

// error3.cpp -- using an exception

#include

double hmean(double a, double b);

int main()

{

    double x, y, z;

    std::cout << "Enter two numbers: ";

    while (std::cin >> x >> y)

    {

        try {                   // start of try block

            z = hmean(x,y);

        }                       // end of try block

        catch (const char * s)  // start of exception handler

        {

            std::cout << s << std::endl;

            std::cout << "Enter a new pair of numbers: ";

            continue;

        }                       // end of handler

        std::cout << "Harmonic mean of " << x << " and " << y

            << " is " << z << std::endl;

        std::cout << "Enter next set of numbers : ";

    }

    std::cout << "Bye!\n";

    return 0;

}

double hmean(double a, double b)

{

    if (a == -b)

        throw "bad hmean() arguments: a = -b not allowed";

    return 2.0 * a * b / (a + b);

}

Here’s a sample run of the program in Listing 15.9:

Enter two numbers: 3 6

Harmonic mean of 3 and 6 is 4

Enter next set of numbers : 10 -10

bad hmean() arguments: a = -b not allowed

Enter a new pair of numbers: 1 19

Harmonic mean of 1 and 19 is 1.9

Enter next set of numbers : q

Bye!

Program Notes

The try block in Listing 15.9 looks like this:

try {                   // start of try block

    z = hmean(x,y);

}                       // end of try block

If any statement in this block leads to an exception being thrown, the catch blocks after this block will handle the exception. If the program calls hmean() somewhere else outside this (and any other) try block, it won’t have the opportunity to handle an exception.

Throwing an exception looks like this:

if (a == -b)

    throw "bad hmean() arguments: a = -b not allowed";

In this case, the thrown exception is the string "bad hmean() arguments: a = -b not allowed". The exception type can be a string, as in this case, or other C++ types. A class type is the usual choice, as later examples in this chapter illustrate.

Executing the throw is a bit like executing a return statement in that it terminates function execution. However, instead of returning control to the calling program, a throw causes a program to back up through the sequence of current function calls until it finds the function that contains the try block. In Listing 15.9, that function is the same as the calling function. Soon you’ll see an example involving backing up more than one function. Meanwhile, in this case, the throw passes program control back to main(). There, the program looks for an exception handler (following the try block) that matches the type of exception thrown.

The handler, or catch block, looks like this:

catch (char * s)  // start of exception handler

{

    std::cout << s << std::endl;

    sdt::cout << "Enter a new pair of numbers: ";

    continue;

}                       // end of handler

The catch block looks a bit like a function definition, but it’s not. The keyword catch identifies this as a handler, and char * s means that this handler matches a thrown exception that is a string. This declaration of s acts much like a function argument definition in that a matching thrown exception is assigned to s. Also, if an exception does match this handler, the program executes the code within the braces.

If a program completes executing statements in a try block without any exceptions being thrown, it skips the catch block or blocks after the try block and goes to the first statement following the handlers. So when the sample run of the program in Listing 15.9 processes the values 3 and 6, program execution goes directly to the output statement and reports the result.

Перейти на страницу:

Все книги серии Developer's Library

Похожие книги