Let’s consider a simple example of exception handling (Figs. 17.1–17.2). We show how to deal with a common arithmetic problem—division by zero. Division by zero using integer arithmetic typically causes a program to terminate prematurely. In floating-point arithmetic, many C++ implementations allow division by zero, in which case a result of positive or negative infinity is displayed as INF
or -INF
, respectively.
1 // Fig. 17.1: DivideByZeroException.h
2 // Class DivideByZeroException definition.
3 #include <stdexcept> // stdexcept header contains runtime_error
4
5 // DivideByZeroException objects should be thrown by functions
6 // upon detecting division-by-zero exceptions
7 class DivideByZeroException : public std::runtime_error
8 {
9 public:
10 // constructor specifies default error message
11 DivideByZeroException()
12 : std::runtime_error( "attempted to divide by zero" ) {}
13 }; // end class DivideByZeroException
1 // Fig. 17.2: fig17_02.cpp
2 // Example that throws exceptions on
3 // attempts to divide by zero.
4 #include <iostream>
5 #include "DivideByZeroException.h" // DivideByZeroException class
6 using namespace std;
7
8 // perform division and throw DivideByZeroException object if
9 // divide-by-zero exception occurs
10 double quotient( int numerator, int denominator )
11 {
12 // throw DivideByZeroException if trying to divide by zero
13 if ( denominator == 0 )
14 throw DivideByZeroException(); // terminate function
15
16 // return division result
17 return static_cast< double >( numerator ) / denominator;
18 } // end function quotient
19
20 int main()
21 {
22 int number1; // user-specified numerator
23 int number2; // user-specified denominator
24
25 cout << "Enter two integers (end-of-file to end): ";
26
27 // enable user to enter two integers to divide
28 while ( cin >> number1 >> number2 )
29 {
30 // try block contains code that might throw exception
31 // and code that will not execute if an exception occurs
32 try
33 {
34 double result = quotient( number1, number2 );
35 cout << "The quotient is: " << result << endl;
36 } // end try
37 catch ( DivideByZeroException ÷ByZeroException )
38 {
39 cout << "Exception occurred: "
40 << divideByZeroException.what() << endl;
41 } // end catch
42
43 cout << "
Enter two integers (end-of-file to end): ";
44 } // end while
45
46 cout << endl;
47 } // end main
Enter two integers (end-of-file to end): 100 7
The quotient is: 14.2857
Enter two integers (end-of-file to end): 100 0
Exception occurred: attempted to divide by zero
Enter two integers (end-of-file to end): ^Z
In this example, we define a function named quotient
that receives two integers input by the user and divides its first int
parameter by its second int
parameter. Before performing the division, the function casts the first int
parameter’s value to type double
. Then, the second int
parameter’s value is (implicitly) promoted to type double
for the calculation. So function quotient
actually performs the division using two double
values and returns a double
result.
Although division by zero is often allowed in floating-point arithmetic, for the purpose of this example we treat any attempt to divide by zero as an error. Thus, function quotient
tests its second parameter to ensure that it isn’t zero before allowing the division to proceed. If the second parameter is zero, the function throws an exception to indicate to the caller that a problem occurred. The caller (main
in this example) can then process the exception and allow the user to type two new values before calling function quotient
again. In this way, the program can continue executing even after an improper value is entered, thus making the program more robust.
The example consists of two files. DivideByZeroException.h
(Fig. 17.1) defines an exception class that represents the type of the problem that might occur in the example, and fig17_02.cpp
(Fig. 17.2) defines the quotient
function and the main
function that calls it. Function main
contains the code that demonstrates exception handling.