Click Here!
home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
[an error occurred while processing this directive]
Previous Table of Contents Next


How It Works

Begin your use of an exception class by examining the source code. Starting at the top of the file, you will find an include directive and immediately following that a using directive.

Next, you come upon the declaration of a class named MathError, as follows:

class MathError
{
public:
    MathError( ) : x(0), y(0) {
    }

    MathError( int x, int y ) : x(x), y(y) {
    }

    void message( ) {
        cout << “MathError exception caught:” << endl ;
        cout << “x==” << x << “, y==” << y << endl ;
    }
private:
    int x, y ;
} ;

This class serves as an exception class. An exception class is used to capture pertinent information about an exception condition. An exception class is used by an application to create objects of that type. In the MathError class, you will find two constructors and a member function named message(). The default constructor is defined inline as is the constructor taking two int arguments.

The message() member function prints out an informational message to include the values of the instance variables. Within the private section, you will find the declarations for two int variables. These variables are used to hold information about a particular exception.

The line of code following the MathError class declaration is a function declaration for divide():

int divide( int x, int y ) throw( MathError ) ;

Notice the exception specification for the divide() function; this function states that it will throw an exception of type MathError and only MathError. If you are unfamiliar with exception specifications, refer to How-To 11.4.

Next, you come to the main function. Starting with the first line of code within main, you will see the declaration of three integer variables.

Following the variable declarations, you come upon the try-catch section of code shown here:

try {
    result = divide( x, y ) ;
}
catch( MathError &m ) {
    m.message() ;
}

The try block consists of a single statement, a call to the function divide(). The divide() function is passed two integer arguments and the result of the call is returned to the variable result.

Now turn your attention to the definition of divide() shown here:

int divide( int x, int y ) throw( MathError )
{
    if( y == 0 )
        throw MathError( x, y ) ;

    return( x / y ) ;
}

Again, you will notice the exception specification for the function. Within the function, the first line checks to see whether the denominator, represented by y, is zero. If y is zero, an exception of type MathError is thrown, otherwise the return statement is executed, returning the result of the expression x/y.

Take note of the throw expression in divide(). An object of type MathError is created, although it is not explicitly shown. The compiler creates a hidden temporary for the constructor call. Next, a copy of this temporary is created and passed to the exception handler. The temporary is then destroyed, even before the exception handling mechanism begins its search for a handler.

Let’s now return to the main function to continue the journey. Turn your attention to the catch clause because the divide() function throws an exception. The catch clause follows:

catch( MathError &m ) {
    m.message() ;
}

The argument to a catch clause can be an object or a reference to an object. If you decide to rethrow an exception, you should consider using a reference as the argument. The most compelling reason is that if you alter the exception object, the changes are reflected in the rethrow of the object. If an object is passed, you operate on only the local object passed in to the catch clause. The following code snippet should illuminate this fact:

catch( MathError m ) {
    m.setMessage( “Divide by zero exception” ) ;
    throw ;
}

In this version, the exception object is a copy of the original object thrown. The call to the member function setMessage() is executed to change the internal message that the exception class will eventually display. The problem with this version is that m is a local object to the catch clause block. This object will cease to exist when the throw is encountered. The next catch clause that handles this exception will not get the altered object. To remedy this problem, you must make m a reference, as shown here:

catch( MathError &m ) {
    m.setMessage( “Divide by zero exception” ) ;
    throw ;
}

Now, the call to setMessage() will operate on the original object, so the next handler to receive the object will realize the changes made in this catch clause.

Comments

You should always consider providing an exception class rather than a simple type. The main reason is that simple types such as int and double do not provide sufficient information in processing an exception condition. An exception class provides a level of detail required to sufficiently handle and report an exception to users.

In this How-To, you saw how to create an exception class and use it. A more robust exception class might write information to a log file or capture additional information about an exception or the environment of the user. The possibilities are limited only by your imagination.

11.4 Specify exceptions that a function will throw?

Problem

I have been using the C++ exception handling mechanism and want to know how I can specify the exceptions thrown by a function. Isn’t there a way to do this without relying on source code comments or documentation?

Technique

This can be a source of confusion to many developers. I have been approached with this question on numerous occasions. This How-To will demonstrate the use of exception specifications.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.