Exception Handling |
|
So far, we have seen that a program is a series of instructions given to the computer to perform specific assignments. These instructions are primarily giver to the compiler to analyze and transmit them further. If the compiler can accurately understand an instruction, it produces a result. If it can't understand it, it may produce an error or just a bad or unreliable result. Once your instructions are clear and understandable, the program may display requests to the user such as expecting a value typed using the keyboard. This means that, even if your primary instructions are correct, a problem may come from an action performed by the user or an external force. Therefore, besides writing code, you also should be able to predict bad actions or behavior that could be performed on your program(s). An exception is an abnormal behavior that could happen to your program. The ability to take care of such a behavior is called exception handling. If you write good instructions in your program and execute it, when a bad value is provided and the program behaves abnormally, the program is said to raise an exception.
The Microsoft implementation of the C language introduced the issue of abnormal behaviors through the Structured Exception Handling (SEH); this is fully supported in (Microsoft) C++ and subsequently in Managed C++. C allows you to create an object on the heap and make sure it is destroyed or gotten rid of. To support this, you first create a section of code that starts with either the try or the __try keywords (Microsoft C++ supports both). The body of this try or __try section must start with an opening curly bracket "{" and must end with a closing curly bracket "}". In this section, known as the body of the try sor __try ection, you can allocate memory and possibly perform any normal assignment that is necessary. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #include ".\school.h" #using <mscorlib.dll> using namespace System; int _tmain() { // TODO: Please replace the sample code below with your own. CSchool __gc *school; try { school = __gc new CSchool; *school->SchoolCapacity = 6248; Console::Write(S"\nScholl Capacity: "); Console::WriteLine(*school->SchoolCapacity); Console::WriteLine(); } return 0; } If you decide to use a try or __try section to allocate memory for an object, you must (normally can) provide a way to destroy the object in a subsequent section. This other section, which must come after the try or __try section, starts with the __finally keyword and has its own body always delimited with curly brackets. Although you can use either try or __try, only the __finally and not the finally is used. In the body the __finally section, you can delete a variable or call a method that closes it. Here is an example // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #include ".\school.h" #using <mscorlib.dll> using namespace System; int _tmain() { // TODO: Please replace the sample code below with your own. CSchool __gc *school; try { school = __gc new CSchool; *school->SchoolCapacity = 6248; Console::Write(S"\nScholl Capacity: "); Console::WriteLine(*school->SchoolCapacity); Console::WriteLine(); } __finally { Console::WriteLine(" - Called __finally, always\n"); delete school; } return 0; } This would produce: The CSchool principal is in the house Scholl Capacity: 6248 - Called __finally, always The CSchool principal is leaving the building Press any key to continue As you can see, the __finally section always executes. It's role in this case is to destroy the object.
The C++ language provides its own support of exception handling. C++ provides three keywords to handle an exception.
As mentioned above, you can create a program that takes exception handling into account as follows: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; int _tmain() { // TODO: Please replace the sample code below with your own. int studentAge; Console::Write(S"Enter Student Age: "); String *strAge = Console::ReadLine(); studentAge = Int32::Parse(strAge); try { Console::WriteLine(S"\nStudent Age: {0}", __box(studentAge)); } catch(...) { } Console::WriteLine(); return 0; } If you run this program and type a positive or negative integer for the students age, the program would respond by displaying the number typed. If you run the program and type a letter or a group of characters and press Enter, the program would crash and display a debugging window: You can then click No to continue.
When your program encounters an exception, there are various ways you can deal with it, you can generate a message and display it to the user, you can define one or more functions to address the exceptions of your program, you can create a central class that manages the exceptions of your program, or you can use the exception classes already available with your programming environment. Rather than spending time creating exceptions from scratch, we will take advantage of the Microsoft .NET Framework's built-in mechanisms of handling exceptions. Managed C++ adds its own flavor or improvement to existing C and C++' exception handling through a vast group of classes. The Microsoft .NET Framework, the main library that Managed C++ uses, features a general class called Exception and defined in the System namespace. Besides supporting Structured Exception Handling (SEH) and C++ exceptions, the System::Exception class provides a main and particular exceptions for various classes of the library, especially those in which a particular action can be taken. Based on this, Managed C++ deals with exceptions in a general concept referred to as Managed Exceptions. A managed exception is an exception that is dealt with in a managed class. To make Managed C++ an effective language, you can write a normal program and let the compiler deal with exceptions as long as you create appropriate try and catch sections in your program. When an exception is thrown, you should present a message to the user to indicate that something bad happened and possibly suggest what the user should do. The Exception class provides messages for various circumstances in a managed application. To use one of these messages, you can pass a pointer to Exception in a catch clause and then access the Message property in the body of the catch section. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; int _tmain() { // TODO: Please replace the sample code below with your own. int studentAge; try { Console::Write(S"Enter Student Age: "); String *strAge = Console::ReadLine(); studentAge = Int32::Parse(strAge); Console::WriteLine(S"\nStudent Age: {0}", __box(studentAge)); } catch(Exception *exc) { Console::WriteLine(exc->Message); } Console::WriteLine(); return 0; } When you execute this program, if you provide a character or a group of characters, the program would not crash but would display a message from the Exception class: Enter Student Age: Allo! Input string was not in a correct format. Press any key to continue
When an exception occurs, the compiler looks for how you decided to handle it. In the above example, the compiler simply finds out that something unusual happened. In this case, a char type was provided as a value for an Int32 type. In this case, and as described already, the compiler would get out of the try section and look for a catch section. Since we provided one that takes an Exception as argument, and it was the only catch section provided, the compiler would use it and end that part of the program. C++ provides better ways of creating, managing or customizing the message(s) displayed to the user. Before specifying how to deal with your own exception, you can start by stating what exception you want to deal with. This is done by creating an if conditional statement followed by a throw keyword. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; int _tmain() { // TODO: Please replace the sample code below with your own. int studentAge; try { Console::Write(S"Enter Student Age: "); studentAge = Int32::Parse(Console::ReadLine()); if( studentAge < 0 ) throw; Console::WriteLine(S"\nStudent Age: {0}", __box(studentAge)); } catch(Exception *exc) { Console::WriteLine(exc->Message); } Console::WriteLine(S""); return 0; } When you use the throw keyword, the compiler proceeds in a top-down approach to analyze the program:
In the above example, we typed a simple throw keyword. If the user provides a negative number to the request, a message would be displayed. Here is an example: Enter Student Age: -25 External component has thrown an exception. Press any key to continue Instead of an empty throw keyword, you can specify the message you want to display to the user. To do this, you can type a string to the right side of throw. Then, create a catch clause that takes a string as argument and displays that message in its section. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; int _tmain() { // TODO: Please replace the sample code below with your own. int studentAge; try { Console::Write(S"Enter Student Age: "); studentAge = Int32::Parse(Console::ReadLine()); if( studentAge < 0 ) throw S"Negative numbers are not allowed"; Console::WriteLine(S"\nStudent Age: {0}", __box(studentAge)); } catch(String* msg) { Console::WriteLine(msg); } Console::WriteLine(S""); return 0; } This time, if the exception that occurs is conform to the conditional statement preceding the throw keyword, your message would display: Enter Student Age: -21 Negative numbers are not allowed Press any key to continue
In the example above, we mostly assumed only one type of exception because we were only concerned with the user typing a negative value as a person's age. As you may suspect, there can be various types of problems that occur during the lifetime of a program. For example, if you write a program that expects a positive number, a user may type a character, a string, or a negative value. In this case, you can prepare your program to deal with these different types of exceptions in the same program. To deal with different exceptions in your program, you can create various catch clauses. The formula to use is
Once again, the compiler would follow a top-down approach. The compiler enters the try section and starts executing the code inside the try section:
Based on this, you can create as many catch clauses as necessary after a try block to dealt with different types of errors. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; int _tmain() { // TODO: Please replace the sample code below with your own. int studentAge; try { Console::Write(S"Enter Student Age: "); studentAge = Int32::Parse(Console::ReadLine()); if( studentAge <= 10 ) throw S"Children 10 or younger are not allowed in this club"; if( studentAge >= 21 ) throw 0; Console::WriteLine(S"\nStudent Age: {0}", __box(studentAge)); } catch(String* msg) { Console::WriteLine(msg); } catch(const int n) { Console::WriteLine(S"Only young adults, less than 21, are considered in this program"); } catch(...) { Console::WriteLine(S"There was a problem with the value you provided"); } Console::WriteLine(S""); return 0; } If the user provides a normal value, this program would behave as expected: Enter Student Age: 15 Student Age: 15 Press any key to continue One test of this program would produce: Enter Student Age: 6 Children 10 or younger are not allowed in this club Press any key to continue Here is another test of the program: Enter Student Age: 24 Only young adults, less than 21, are considered in this program Press any key to continue Another test of the program would produce: Enter Student Age: Hello There was a problem with the value you provided Press any key to continue
As mentioned already, the Exception class provides a Message property used to display a message to the user about an error. Instead of, or as opposed to, creating a normal string after the throw keyword, you can create and pass your message to the Exception class. To create your own message, in the section where you anticipate the exception, type the throw keyword followed by the new keyword and call one of the constructors of the Exception class you want or need to call. The parent class itself offers four constructors, one of which takes as argument a String. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; int _tmain() { // TODO: Please replace the sample code below with your own. int studentAge; try { Console::Write(S"Enter Student Age: "); studentAge = Int32::Parse(Console::ReadLine()); if( studentAge <= 10 ) throw new Exception(S"Children 10 or younger are not allowed in this club"); if( studentAge >= 21 ) throw 0; Console::WriteLine(S"\nStudent Age: {0}", __box(studentAge)); } catch(Exception *e) { Console::WriteLine(e->Message); } catch(const int) { Console::WriteLine(S"Only young adults, less than 21, are considered in this program"); } catch(...) { Console::WriteLine(S"There was a problem with the value you provided"); } Console::WriteLine(S""); return 0; } In the above example, we considered two cases of numbers, less than 11 and greater than 20. These two exceptions are based on a numeric value. Instead of writing different catch clauses to deal with these exceptions, you can write a single catch clause that takes a numeric value as argument. Then, in the body of the catch, you can consider each possibility and act accordingly. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; int _tmain() { // TODO: Please replace the sample code below with your own. int studentAge; try { Console::Write(S"Enter Student Age: "); studentAge = Int32::Parse(Console::ReadLine()); if( studentAge <= 10 ) throw 1; if( studentAge >= 21 ) throw 2; Console::WriteLine(S"\nStudent Age: {0}", __box(studentAge)); } catch(const int n) { if( n == 1 ) Console::WriteLine(S"Children 10 or younger are not allowed in this club"); if( n == 2 ) Console::WriteLine(S"Only young adults, less than 21, are considered in this program"); } catch(...) { Console::WriteLine(S"There was a problem with the value you provided"); } Console::WriteLine(S""); return 0; }
|
|
||
Previous | Copyright © 2004 FunctionX, Inc. | Next |
|