Title: Handling%20Exceptions
1Handling Exceptions
Lecture 11
2Objectives
- In this lecture, you will learn
- About the limitations of traditional
error-handling methods - How to throw exceptions
- How to use try blocks
- How to catch exceptions
- How to use multiple throw statements and multiple
catch blocks - How to throw objects
- How to use the default exception handler
- How to use exception specifications
- About unwinding the stack
- How to handle memory allocation exceptions
3Understanding the Limitations of Traditional
Error Handling
- Many C programs contain code similar to the
code in Figure 12-1 - The program uses the exit() function, which
forces the program to end - When you use the exit() function, the program
ends abruptly - If the program is a spreadsheet or a game, the
user might become annoyed that the program has
prematurely stopped working
4Understanding the Limitations of Traditional
Error Handling
Ex11-1.cpp
- A slightly better alternative to exit() involves
using the atexit() function - The atexit() function requires a function name as
its argument this function is then registered
with atexit(), which means the named function is
called automatically whenever the exit() function
executes
5Understanding the Limitations of Traditional
Error Handling
- A general rule of modular programming is that a
function should be able to determine an error
situation but not necessarily take action on it - The function in Figure 12-4 returns a 1 if the
dataEntryRoutine() function detects an error, and
a 0 if it does not
6Understanding the Limitations of Traditional
Error Handling
- The calling main() function checks the return
value of the function and takes appropriate
action, printing an error message or not - However, this error-handling technique has at
least two drawbacks based on the following rules - A function can return, at most, only one value
- When a function returns a value, it must return
only the type indicated as its return type - In the example in Figure 12-4, you could work
around the problem of losing one of the values by
rewriting the dataEntryRoutine() function so that
sometimes it returns the userEntry, and sometimes
it returns the error code
7Program that Uses dataEntryRoutine() with Error
Code
8Understanding the Limitations of Traditional
Error Handling
- As another remedy, you could write the
dataEntryRoutine() function so it accepts the
address of the userEntry variable from main() - However, allowing functions to access and alter
passed variable values violates the general
principle of encapsulation, and increases the
data coupling of the function - Second, any error code returned by a function
must be the same type as the functions return
type
9Throwing Exceptions
- A function can contain code to check for errors,
and send a message when it detects an error - In object-oriented terminology, an exception is a
message (an object) that is passed from the place
where a problem occurs to another place that will
handle the problem - The general principle underlying good
object-oriented error handling is that any called
function should check for errors, but should not
be required to handle an error if one is found
10Throwing Exceptions
- When an object-oriented program detects an error
within a function, the function should send an
error message to the calling function, or throw
an exception - A throw resembles a return statement in a
function, except that the execution of the
program does not continue from where the function
was called
11Throwing Exceptions
- You throw an exception by using the keyword throw
followed by any C object, including an object
that is a built-in scalar type, such as an int or
a double a nonscalar type, such as a string or
numeric array or even a programmer-defined
object - A function can make more than one throw
12Throwing Exceptions
- When you use the version of the dataEntry()
function shown in Figure 12-7, if the user enters
a value between 0 and 12 inclusive, the actual
value is returned to the calling function when
the function ends
13Using Try Blocks
- A try block consists of one or more statements
that the program attempts to execute, but that
might result in thrown exceptions - A try block includes the following components
- The keyword try
- An opening curly brace
- The code that is tried
- A closing curly brace
14A main() Function Containing a Try Block
15Using Try Blocks
- In Figure 12-8, the call to the dataEntry()
function occurs within the highlighted try block - When dataEntry() executes, if the userEntry is
valid, then no exception is thrown, and main()
executes to the end, using the valid value
returned by the dataEntry() function - If the dataEntry() function is called from a try
block, as in Figure 12-8, then you can deal with
the error situation more elegantly and less
abruptly than with an exit() call - You handle the thrown exception by catching it
16Catching Exceptions
- To handle a thrown object, you include one or
more catch blocks in your program immediately
following a try block - A catch block includes the following components
- The keyword catch
- A single argument in parentheses
- An opening curly brace
- One or more statements that describe the
exception action to be taken - A closing curly brace
- Figure 12-9 shows a dataEntry() function that
throws a string error message if the user enters
a negative number
17Catching Exceptions
18Catching Exceptions
Ex11-2.cpp
- After executing the catch block, the main()
program continues - The value shown is garbage because in the
program, userValue is assigned a valid value only
when dataEntry() is completed
19Catching Exceptions
- To avoid seeing this garbage value, you could
take one of several actions - Initialize userValue when it is declared in the
main() function its value will change only if
the try block is successful - Assign a dummy value to userValue within the
catch block, as well as within the try block. If
the try block is successful, then userValue holds
the value entered by the user. If the try block
is unsuccessful, then userValue holds the
assigned dummy value - Declare a flag variable set to 0, then set it to
1 within the catch block to indicate an exception
was thrown.
20Catching Exceptions
- If you want a catch block to execute, it must
catch the correct type of argument thrown from a
try block - In the steps reviewed on pages 455 to 456 of the
textbook, you create a passwordEntry() function
that asks a user to supply a password
21Catching Exceptions
Ex11-3.cpp
22Using Multiple Throw Statements and Multiple
Catch Blocks
- You can write a function to throw any number of
exceptions, and you can provide multiple catch
blocks to react appropriately to each type of
exception that is thrown - You can create a dataEntry() function that throws
a string message when the user enters a negative
number, but throws an invalid value when the user
enters a number that is more than 12 - When you run the program in Figure 12-14, if no
exception is thrown, the program bypasses both
catch blocks and prints the valid value, as shown
in Figure 12-15
23A dataEntry() Function that Throws Two Types of
Exceptions
24Using Multiple Throw Statements and Multiple
Catch Blocks
Ex12-4
25Throwing Objects
- Just as simple variables such as doubles,
integers, and strings can be thrown via
exception-handling techniques, programmer-defined
class objects also can be thrown - This approach is particularly useful in two types
of situations - If a class object contains errors, you may want
to throw the entire object, rather than just one
data member or a string message - Whenever you want to throw two or more values,
you can encapsulate them into a class object so
that they can be thrown together
26Throwing Standard Class Objects
- Figure 12-19 shows an Employee class with two
data fields, empNum and hourlyRate - The insertion operator is overloaded in the same
way you have seen it coded in many other classes,
but in this Employee class, the extraction
operator has been overloaded to throw an
exception - Any program that uses the Employee class can
catch the thrown Employee object and handle it
appropriately for the application
27The Employee Class
28Throwing Standard Class Objects
- A few possibilities include
- A program might assign default values to any
Employee whose data entry resulted in an
exception - A program that tests the accuracy of data entry
operators might store caught exceptions just as
they are entered and count them - A program that is used when hiring Employees for
a special assignment that pays more than the
usual maximum might ignore the high-end salary
violations - A program might refuse to accept an Employee with
an exception, and force the user to re-enter the
values, as in the main() program shown in Figure
13-20
29A main() Program that Instantiates Three Employee
Objects
30Throwing Standard Class Objects
Ex11-5.cpp
- The program in Figure 12-20 declares an array of
three Employee objects - When you include multiple catch blocks in a
program, the first catch block that can accept a
thrown object is the one that will execute
31Throwing Exception Objects
- You can create a class that represents an
exception - Figure 12-22 shows a Customer class that is
similar to many classes you already have worked
with - Each Customer holds data fields for a customer
number and a balance due, and has access to
overloaded extraction and insertion operators
that you can use for input and output
32The Customer Class
33Throwing Exception Objects
- Figure 12-23 shows the CustomerException class
- Its data members include a Customer object and a
string message, and its constructor requires
values for both
34Throwing Exception Objects
- Figure 12-24 shows a main() program that declares
an array of four Customer objects - In this program a loop contains four calls to the
overloaded operator gtgt() function - Figure 12-25 shows the output of a typical
execution of the program in which some of the
Customers exceed the credit limit and others do
not
35Program that Instantiates Four Customers
36Output of Typical Execution of the
CustomerException Program
Ex11-6.cpp
37Using the Default Exception Handler
- When any object is thrown with a throw statement,
then a subsequent catch block has a usable match
if one of the following conditions is true - The type of the thrown object and the type of the
catch argument are identical (for example, int
and int) - The type of the thrown object and the type of the
catch argument are the same, except the catch
contains the const qualifier, a reference
qualifier, or both (for example, int can be
caught by const int, int, or const int) - The catch argument type is a parent class of the
thrown argument
38Using the Default Exception Handler
Ex11-7.cpp
- If you throw an argument and no catch block
exists with an acceptable argument type, then the
program terminates - To avoid termination, you can code a default
exception handler that catches any type of object
not previously caught - Ex11-7.cpp demonstrate that a default catch block
works as expected - You create an Order class whose data entry
function accepts several values and throws a
variety of exception types
39Unwinding the Stack
- When you write a function, you can try a function
call and, if the function you call throws an
exception, you can catch the exception - However, if your function that calls the
exception-throwing function doesnt catch the
exception, then a function that calls your
function can still catch the exception - A simpler way to say this is that if function A
calls function B, and function B calls function
C, and function C throws an exception, then if B
does not catch the exception, function A can
40Unwinding the Stack
- If no function catches the exception, then the
program terminates - This process is called unwinding the stack,
because each time you call a function, the
address of the place to which the program should
return is stored in a memory location called the
stack - Figure 12-28 shows a KennelReservation class that
holds information about boarding a Do - Each KennelReservation includes a kennel number,
a month and day for the reservation, and a Dog
41The Dog Class
42The KennelReservation Class
Ex11-8.cpp
43Unwinding the Stack
- Within the KennelReservation function in Figure
12-28, both highlighted exception specifications
could be deleted, and the class still would
function properly - Figure 12-29 shows a main() function that
instantiates a KennelReservation object, and
Figure 12-30 shows a typical execution
44Unwinding the Stack
45Summary
- A popular traditional way to handle error
situations was to terminate the program - A superior alternative to traditional
error-handling techniques is called exception
handling - The general principle underlying good
object-oriented error handling is that any
function that is called should check for errors,
but should not be required to handle an error if
it finds one - When a function might cause an exception, and
therefore includes a throw statement to handle
errors, the call to potentially offending
functions should be placed within a try block
46Summary
- To handle a thrown object, you include one or
more catch blocks in your program immediately
following a try block - If you want a catch block to execute, it must
catch the correct type of argument thrown from a
try block - You can write a function to throw any number of
exceptions, and you can provide multiple catch
blocks to react appropriately to each type of
exception that is thrown
47Summary
- Just as simple variables such as doubles,
integers, and strings can be thrown via
exception-handling techniques, so can
programmer-defined class objects - You can create a class that represents an
exception - The class is instantiated only when an exception
occurs
48Summary
12
- If you throw an argument and no catch block
exists with an acceptable argument type, then the
program terminates - You can explicitly indicate the exception that a
function can possibly throw by writing an
exception specification, which is a declaration
of a functions possible throw types - When you allocate memory, it is always possible
that there is not enough memory available, so the
creators of C have created an out of memory
exception handler for you called set_new_handler()