Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Handling Exceptions COSC 1567 C++ Programming Lecture 11.

Similar presentations


Presentation on theme: "1 Handling Exceptions COSC 1567 C++ Programming Lecture 11."— Presentation transcript:

1 1 Handling Exceptions COSC 1567 C++ Programming Lecture 11

2 2 Objectives 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

3 3 Understanding 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

4 4 Understanding the Limitations of Traditional Error Handling 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 Ex11-1.cpp

5 5 Understanding 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

6 6 Understanding 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

7 7 Program that Uses dataEntryRoutine() with Error Code

8 8 Understanding 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 function’s return type

9 9 Throwing 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

10 10 Throwing 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

11 11 Throwing 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

12 12 Throwing 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

13 13 Using 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

14 14 A main() Function Containing a Try Block

15 15 Using 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

16 16 Catching 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

17 17 Catching Exceptions

18 18 Catching Exceptions 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 Ex11-2.cpp

19 19 Catching 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.

20 20 Catching 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

21 21 Catching Exceptions Ex11-3.cpp

22 22 Using 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

23 23 A dataEntry() Function that Throws Two Types of Exceptions

24 24 Using Multiple Throw Statements and Multiple Catch Blocks Ex12-4

25 25 Throwing 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

26 26 Throwing 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

27 27 The Employee Class

28 28 Throwing 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

29 29 A main() Program that Instantiates Three Employee Objects

30 30 Throwing Standard Class Objects 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 Ex11-5.cpp

31 31 Throwing 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

32 32 The Customer Class

33 33 Throwing 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

34 34 Throwing 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 >>() 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

35 35 Program that Instantiates Four Customers

36 36 Output of Typical Execution of the CustomerException Program Ex11-6.cpp

37 37 Using 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

38 38 Using the Default Exception Handler 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 Ex11-7.cpp

39 39 Unwinding 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 doesn’t 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

40 40 Unwinding 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

41 41 The Dog Class

42 42 The KennelReservation Class Ex11-8.cpp

43 43 Unwinding 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

44 44 Unwinding the Stack

45 45 Summary 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

46 46 Summary 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

47 47 Summary 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

48 48 Summary 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 function’s 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() 12


Download ppt "1 Handling Exceptions COSC 1567 C++ Programming Lecture 11."

Similar presentations


Ads by Google