Presentation is loading. Please wait.

Presentation is loading. Please wait.

Handling ErrorstMyn1 Handling Errors Up to this point we haven't worried much about errors or exceptions. First, let's distinguish between errors and exceptions.

Similar presentations


Presentation on theme: "Handling ErrorstMyn1 Handling Errors Up to this point we haven't worried much about errors or exceptions. First, let's distinguish between errors and exceptions."— Presentation transcript:

1 Handling ErrorstMyn1 Handling Errors Up to this point we haven't worried much about errors or exceptions. First, let's distinguish between errors and exceptions. An error typically refers to a problem that exists in a program when it is written and compiled. It could be a logic error that will result in incorrect results. In this case, the code is correct but the algorithm has an error. This type of error will only be found during program testing or during design reviews of the program.

2 Handling ErrorstMyn2 Another type of error is a syntax error. Typically, the compiler finds errors of this type and they are corrected during the coding of the program. Exceptions are errors or anomalies that occur during the execution of a program. They can be the result of unavailability of system resources, such as memory, file space, channels or from data dependent conditions such as a divide by zero, or numerical overflow. Exceptions tend to be rare events but are predicable to some extent. Given that exceptions are somewhat predicable, how should our programs handle them?

3 Handling ErrorstMyn3 Broadly, there are three types of responses we can take: 1. Not handle the exception. Allow the program to die or core dump. 2. Issue a warning. Print out some type of error message, probably at the spot in the code where the exception occurred and then exit. 3. Handle the exception gracefully and continue executing.

4 Handling ErrorstMyn4 Certainly, the first way, doing nothing is not acceptable if you want to remain employed or pass your courses. The second way is a little better. Information about the exception is written out, but this is still not ideal. Most real world programs need to be more robust than this. Exceptions need to be handled and corrected. Execution must continue. Your mission to reach Mars can't fail due to a divide by zero. Since we must handle exceptions, what features would assist us? Should the same section of code be raising the exception and handling the exception?

5 Handling ErrorstMyn5 Suppose an exception occurs in allocating memory. Should the function that attempted the allocation be the one to handle it? Can it (obviously not!)? Probably some other, higher level, section of code will have the information necessary to decide how to handle the exception. Maybe different programs using the same classes and functions will handle exceptions differently. This points to a separation of the creation of an exception and its handling. The function in which an exception occurs could just alert its caller. This allows code that raises exceptions to be developed separately from code that handles them.

6 Handling ErrorstMyn6 If we pass exceptions up to calling routines, it is necessary to have a way to bundle information and for the exception to have some methods to assist in its handling. The C++ exception mechanism handles both these features: 1. Exceptions may be raised and handled in different sections of code. 2. Any object, including class objects may be passed back to the handler of an exception. These objects can contain data and methods to assist in handling the exception.

7 Handling ErrorstMyn7 The section of code that causes or detects a run-time abnormality (divide by zero, out of memory) will "throw" an exception. The exception is the object that is thrown. It may be a simple object such as an int, or a class object, including programmer defined class objects. The exception is "caught" by another section of code. The exception object, itself, is used to convey information from the section of code that throws the object to the section of code that catches the object. This separation of exception creation and exception handling is very significant.

8 Handling ErrorstMyn8 Higher level sections of code can better handle exceptions in many cases. Suppose an exception occurs in a library routine. That routine cannot know how to respond in a way that is appropriate for your program. In some cases the appropriate response might be to terminate the program. In other cases, the appropriate response might be a warning message. In others, maybe the exception can be caught and disregarded.

9 Handling ErrorstMyn9 Sections of code that can throw exceptions are surrounded in try blocks. Exceptions thrown from within try blocks are caught by a catch clause. Let's make this more concrete with a simple example.

10 Handling ErrorstMyn10 #include "stdafx.h" #include using namespace System; using namespace std; int main(array ^args) { int x,y; double result; int exception=57; cout<<"Input integer: "; cin>>x; cin.get(); cout<<"Input another integer: "; cin>>y; cin.get();

11 Handling ErrorstMyn11 try { if(y==0) throw exception; result=static_cast (x)/y; cout<<"The division gives "<<result<<"."<<endl; } catch(int eValue) { if(eValue==57) cout <<"Divide by zero!"<<endl; else cout <<"Exception of unknown type!"<<endl; cout<<"Goodbye!"<<endl; } return 0; }

12 Handling ErrorstMyn12 The output would be: or:

13 Handling ErrorstMyn13 First, notice that the section of code that tests for an anomalous condition and throws an exception is within a try block. In this example the catch block immediately follows the try block, although, this is not a necessity. Let's trace through the execution of this program. As execution enters the try block, the condition "y == 0" is evaluated and is true. The code in the "if" block is executed. An exception is thrown and execution jumps to the catch block that follows the try block. Since the type of the exception is an "int" and the catch clause matches "int", the clause is executed and an error message is printed.

14 Handling ErrorstMyn14 Note that the code immediately following the "throw", " result=static_cast (x)/y " is skipped. Also, note that after the exception is caught, execution continues with the code that follows that catch block. It does not return to the section of code following the throw. The variable "result" is never calculated. The exception thrown is of type int and the catch block contains logic to decode this value and print an appropriate error message. This is bad design because it requires the catch block and its programmer to implement possibly complex logic and to be aware of possible exception codes.

15 Handling ErrorstMyn15 Let's see how to improve this code. Remember an exception can be any type of object. Let's try throwing the error message string itself, rather than an exception code.

16 Handling ErrorstMyn16 #include "stdafx.h" #include using namespace System; using namespace std; int main(array ^args) { int x,y; double result; cout<<"Input integer: "; cin>>x; cin.get(); cout<<"Input another integer: "; cin>>y; cin.get();

17 Handling ErrorstMyn17 try { if(y==0) { string exception="Divide by zero!"; throw exception; } result=static_cast (x)/y; cout<<"The division gives "<<result<<"."<<endl; } catch(string except) { cout<<except<<endl <<"Goodbye!"<<endl; } return 0; }...and the output is exactly as previously.

18 Handling ErrorstMyn18 This is better. The catch block no longer needs detailed knowledge about the exception. The code that throws the exception is passing details, in this case an error message.

19 Handling ErrorstMyn19 In C++, an exception is usually a class object. This allows more information to be bundled into the exception and also allows the exception to contain functions to assist the sections of code that handle or process the exception. An exception class is just a class. What makes it an exception class is how it is used. Let ’ s have a simple example:

20 Handling ErrorstMyn20 #include "stdafx.h" #include using namespace System; using namespace std; class noMilk { public: noMilk(int); int getDonuts(); private: int count; }; noMilk::noMilk(int howMany) { count=howMany; }

21 Handling ErrorstMyn21 int noMilk::getDonuts() { return count; } int main(array ^args) { int donuts, milk; double result; try { cout<<"Enter number of donuts: "; cin>>donuts; cin.get(); cout<<"Enter number of glasses of milk: ";

22 Handling ErrorstMyn22 cin>>milk; cin.get(); if (milk==0) throw noMilk(donuts); result=donuts/static_cast (milk); cout<<donuts<<" donuts."<<endl <<milk<<" glasses of milk."<<endl <<"You have "<<result <<" donuts for each glass of milk!"<<endl; } catch (noMilk nMObject) { cout<<nMObject.getDonuts() <<" donuts and no milk!"<<endl <<"Go and buy some milk!"<<endl; } return 0; }

23 Handling ErrorstMyn23 …and the output is either or…

24 Handling ErrorstMyn24 Notice the throw-statement: throw noMilk(donuts); The part noMilk(donuts) is an invocation of a constructor for class noMilk. The constructor takes one int argument (in this case donuts) and creates an object of the class noMilk. The object is then “thrown”.

25 Handling ErrorstMyn25 A try-block can potentially throw any number of exception values, and they can be of differing types. In any one exception of the try-block only one exception will be thrown (since a thrown exception ends the execution of the try-block), but different types of exception values can be thrown on different occasions when the try-block is executed. Each catch-block can only catch values of one type, but you can catch exception values of differing types by placing more than one catch-block after a try- block.

26 Handling ErrorstMyn26 Let’s modify the last example so that the main part is more in line with the object oriented programming:

27 Handling ErrorstMyn27 #include "stdafx.h" #include using namespace System; using namespace std; class noMilk { public: noMilk(); noMilk(int); int getDonuts(); protected: int count; }; noMilk::noMilk() {}

28 Handling ErrorstMyn28 noMilk::noMilk(int howMany) { count=howMany; } int noMilk::getDonuts() { return count; } class Breakfast: public noMilk { public: Breakfast(); void recommendations(); private: int donuts, milk; };

29 Handling ErrorstMyn29 Breakfast::Breakfast() { cout<<"Enter number of donuts: "; cin>>donuts; cin.get(); cout<<"Enter number of glasses of milk: "; cin>>milk; cin.get(); }

30 Handling ErrorstMyn30 void Breakfast::recommendations() { double result; try { if (milk==0) throw noMilk(donuts); result=donuts/static_cast (milk); cout<<donuts<<" donuts."<<endl <<milk<<" glasses of milk."<<endl <<"You have "<<result <<" donuts for each glass of milk!"<<endl; }

31 Handling ErrorstMyn31 catch (noMilk nMObject) { cout<<nMObject.getDonuts() <<" donuts and no milk!"<<endl <<"Go and buy some milk!"<<endl; } int main(array ^args) { Breakfast first=Breakfast(); first.recommendations(); return 0; }


Download ppt "Handling ErrorstMyn1 Handling Errors Up to this point we haven't worried much about errors or exceptions. First, let's distinguish between errors and exceptions."

Similar presentations


Ads by Google