![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
[an error occurred while processing this directive]
How It Works Starting at the top of the file, you will find two include directives and a using directive. Next, you will see function declarations for rethrowFunc() and throwFunc(). The purpose of the throwFunc() function is to throw different types of exceptions. The rethrowFunc() functions purpose is to catch exceptions thrown by throwFunc() and to then rethrow the exceptions. These two functions are examined in more detail later in this section. But first, lets continue our journey into the main function. The first statement in main is a for loop. The for loop provides the logic to iterate through all the exceptions to throw without excessive lines of code. The first block of code within the for loop is the try block: try { rethrowFunc( i ) ; } As the code begins its journey down the loop, it enters the try block and encounters the call to rethrowFunc(). The function is passed the value of i as its argument. Lets take a quick diversion to rethrowFunc()s definition. This discussion will only look at the first few lines, as follows: void rethrowFunc( int i ) { try { throwFunc( i ) ; cout << rethrowFunc() << endl ; } //... The first logical block of code in this function is another try block. This try block is independent of the try block found in the main function. The only statement found within the try is a call to the function throwFunc(). Notice that the original value of i from main is again passed to throwFunc(). Because program flow is again being redirected, lets divert our attention to the definition of throwFunc(). The body of throwFunc() follows: void throwFunc( int i ) { int x = 5, y = 0, r = 0 ; switch( i ) { case 0: throw( int(5) ) ; break ; case 1: throw( float(10.5) ) ; break ; case 2: throw( double(21.0) ) ; break ; case 3: throw( an exceptional string ) ; break ; default: r = x / y ; break ; } } The first statement in the function declares three integers for use in a subsequent expression within the function. Next you find a switch statement, its argument being the argument to the function. Remember that this argument is the original value of the integer used in the for loop in main. This provides a unique value to switch on, so that a different throw can be demonstrated. Depending on the value, a different case statement is executed. This function will throw one of five types of exceptions: int, float, double, char*, or divide-by-zero. The last one, divide-by-zero, is defined by the Standard; it is why the exception header file was included. Take a look at the default block; if you examine the values of the variables, this expression divides 5 by 0, obviously a mathematical no-no. The reason I added this line of code will be obvious later in this section. Beyond the switch and throw statements, not much else happens in this function. Although simple, it provides the logic required to rethrow exceptions and demonstrate multiple catch clauses. Lets now return to the rethrowFunc() function definition. Here it is again in its entirety: void rethrowFunc( int i ) { try { throwFunc( i ) ; cout << rethrowFunc() << endl ; } catch( int v ) { throw ; } catch( float f ) { throw ; } catch( double d ) { throw ; } catch( char *s ) { throw ; } catch( ... ) { throw ; } } Pay particular attention to the cout statement. If you recall the output of this program, this statement is never executed. Again, here is the output: Int caught: 5 Float caught: 10.5 Double caught: 21 Char* caught: an exceptional string Other exception caught Other exception caught Remember that because throwFunc() throws an exception, any statement following the call to throwFunc() within the try block will not be executed. Control will instead be diverted to the catch clause that can handle the exception. Look again at the previous function definition. Notice that each catch clause contains a single throw expression. This is referred to as a rethrow expression. When the exception mechanism encounters a throw expression within a catch clause, the same exception will be thrown again. You should provide rethrow logic any time you think the exception should be handled further up the call chain. You have to be cautious when dealing with rethrow logic. If, for example, you modify the exception object and then execute a throw expression, the changes to the object might not be what you expect. A nonreference object that is passed as an argument to a catch clause will get a copy of the original object. Therefore, if you modify the object, you will modify only the local copy. The following example demonstrates this: catch( int val ) { val = 32000 ; throw ; }
|
![]() |
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|