You are on page 1of 21

16

Exception
Handling
I never forget a face, but
in your case Ill make an
exception.
Groucho Marx

It is common sense to take a


method and try it. If it fails,
admit it frankly and try
another. But above all, try
something.

OBJECTIVES
In this chapter you will learn:

What exceptions are and when to use them.

Franklin Delano Roosevelt

O! throw away the


worser part of it,
And live the purer
with the other half.

To process uncaught and unexpected exceptions.

To declare new exception classes.

William Shakespeare

If theyre running and they


dont look where theyre going
I have to come out from
somewhere and catch them.
Jerome David Salinger

To use try, catch and throw to detect, handle and


indicate exceptions, respectively.

How stack unwinding enables exceptions not caught in


one scope to be caught in another scope.

To handle new failures.

To use auto_ptr to prevent memory leaks.

To understand the standard exception hierarchy.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Chapter 16 Exception Handling

O innite virtue! comst thou smiling from the worlds great snare uncaught?
William Shakespeare

Self-Review Exercises
16.1

List five common examples of exceptions.


ANS: Insufficient memory to satisfy a new request, array subscript out of bounds, arithmetic
overflow, division by zero, invalid function parameters.

16.2 Give several reasons why exception-handling techniques should not be used for conventional program control.
ANS: (a) Exception handling is designed to handle infrequently occurring situations that
often result in program termination, so compiler writers are not required to implement exception handling to perform optimally. (b) Flow of control with conventional control structures generally is clearer and more efficient than with exceptions. (c)
Problems can occur because the stack is unwound when an exception occurs and resources allocated prior to the exception might not be freed. (d) The additional exceptions make it more difficult for the programmer to handle the larger number of
exception cases.
16.3

Why are exceptions appropriate for dealing with errors produced by library functions?

ANS: It is unlikely that a library function will perform error processing that will meet the

unique needs of all users.

16.4

What is a resource leak?


ANS: A program that terminates abruptly could leave a resource in a state in which other
programs would not be able to acquire the resource, or the program itself might not
be able to reacquire a leaked resource.

16.5 If no exceptions are thrown in a try block, where does control proceed to after the try block
completes execution?
ANS: The exception handlers (in the catch handlers) for that try block are skipped, and
the program resumes execution after the last catch handler.
16.6
16.7

What happens if an exception is thrown outside a try block?

ANS: An exception thrown outside a try block causes a call to terminate.

Give a key advantage and a key disadvantage of using catch(...).

ANS: The form catch(...) catches any type of exception thrown in a try block. An ad-

vantage is that all possible exceptions will be caught. A disadvantage is that the catch
has no parameter, so it cannot reference information in the thrown object and cannot
know the cause of the exception.

16.8

16.9

What happens if no catch handler matches the type of a thrown object?


ANS: This causes the search for a match to continue in the next enclosing try block if there
is one. As this process continues, it might eventually be determined that there is no
handler in the program that matches the type of the thrown object; in this case, terminate is called, which by default calls abort. An alternative terminate function can
be provided as an argument to set_terminate.
What happens if several handlers match the type of the thrown object?

ANS: The first matching exception handler after the try block is executed.

16.10 Why would a programmer specify a base-class type as the type of a


throw objects of derived-class types?
ANS: This is a nice way to catch related types of exceptions.

catch

handler, then

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises

16.11 Suppose a catch handler with a precise match to an exception object type is available. Under what circumstances might a different handler be executed for exception objects of that type?
ANS: A base-class handler would catch objects of all derived-class types.
16.12 Must throwing an exception cause program termination?
ANS: No, but it does terminate the block in which the exception is thrown.
16.13 What happens when a catch handler throws an exception?
ANS: The exception will be processed by a catch handler (if one exists) associated with the
try block (if one exists) enclosing the catch handler that caused the exception.
16.14 What does the statement throw; do?
ANS: It rethrows the exception if it appears in a catch handler; otherwise, function unexpected is called.
16.15 How does the programmer restrict the exception types that a function can throw?
ANS: Provide an exception specification listing the exception types that the function can
throw.
16.16 What happens if a function throws an exception of a type not allowed by the exception
specification for the function?
ANS: Function unexpected is called.
16.17 What happens to the automatic objects that have been constructed in a try block when that
block throws an exception?
ANS: The try block expires, causing destructors to be called for each of these objects.

Exercises
16.18 List various exceptional conditions that have occurred throughout this text. List as many
additional exceptional conditions as you can. For each of these exceptions, describe briefly how a
program typically would handle the exception, using the exception-handling techniques discussed
in this chapter. Some typical exceptions are division by zero, arithmetic overflow, array subscript
out of bounds, exhaustion of the free store, etc.
ANS: A few examples are: Division by zerocheck the denominator to see if it is equal to
zero, and throw an exception before the division occurs. Array subscript out of
boundscatch the exception, print an error message telling the user what index was
trying to be referenced, and exit the program in a controlled manner. Exhaustion of
the free storecatch the exception, and either deallocate enough other objects so
that you can allocate memory for the new object or delete all objects and terminate
the program. Bad castcatch the exception and either cast the operand to the proper
type, if that can be determined, or print an error message indicating what the bad cast
was, and exit the program.
16.19 Under what circumstances would the programmer not provide a parameter name when defining the type of the object that will be caught by a handler?
ANS: If there is no information in the object that is required in the handler, a parameter
name is not required in the handler.
16.20 A program contains the statement
throw;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Chapter 16 Exception Handling

Where would you normally expect to find such a statement? What if that statement appeared in a
different part of the program?
ANS: The statement would be found in an exception handler to rethrow an exception. If
any throw; expression occurs outside a try block, the function unexpected is called.
16.21 Compare and contrast exception handling with the various other error-processing schemes
discussed in the text.
ANS: Exception handling enables the programmer to build more robust classes with builtin error-processing capabilities. Once created, such classes allow clients of classes to
concentrate on using the classes rather than defining what should happen if an error
occurs while using the class. Exception handling also allows a program that should
not continue to exit in a controlled manner, returning any resources that it might
have obtained, therefore preventing possible resource leaks, and it allows the program
to display messages about the problem, instead of just terminating. Exception handling provides a single, uniform technique for processing errors; this can help programmers working on large projects to understand each others error-processing
code.
16.22 Why should exceptions not be used as an alternate form of program control?
ANS: Exception is designed to handle infrequently occurring situations that often result in
program termination. Exceptions do not follow conventional forms of program control. Handling a larger number of exception cases can be cumbersome, and programs
with a large number of exception cases can be difficult to read and maintain.
16.23 Describe a technique for handling related exceptions.
ANS: Create a base class for all related exceptions. From the base class, derive related exception classes. Once the exception class hierarchy is created, all exceptions from the hierarchy can be caught as the base class exception type.
16.24 Until this chapter, we have found that dealing with errors detected by constructors can be
awkward. Exception handling gives us a better means of handling such errors. Consider a constructor for a String class. The constructor uses new to obtain space from the free store. Suppose new fails.
Show how you would deal with this without exception handling. Discuss the key issues. Show how
you would deal with such memory exhaustion with exception handling. Explain why the exceptionhandling approach is superior.
16.25 Suppose a program throws an exception and the appropriate exception handler begins executing. Now suppose that the exception handler itself throws the same exception. Does this create
infinite recursion? Write a program to check your observation.
ANS: No, this would not create an infinite recursion; instead the program would be terminated abnormally, because there is no handler for TestException thrown at line 18.
1
2
3
4
5
6
7
8
9
10
11
12

// Exercise 16.25 Solution: TestException.h


#include <string>
using std::string;
#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class TestException definition
class TestException : public runtime_error
{
public:
// constructor specifies error message

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
13
14
15

TestException::TestException( const string& message )


: runtime_error( message ) {}
}; // end class TestException

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// Exercise 16.25 Solution: Ex16_25.cpp


#include <iostream>
using std::cerr;
using std::endl;

#include "TestException.h"
int main()
{
// throw same exception from catch handler
try
{
throw TestException( "This is a test" );
} // end try
catch ( TestException &t )
{
cerr << t.what() << endl;
throw TestException( "This is another test" );
} // end catch
return 0;
} // end main

This is a test
abnormal program termination

16.26 Use inheritance to create various derived classes of runtime_error. Then show that a catch
handler specifying the base class can catch derived-class exceptions.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.26 Solution: DerivedException1.h


#include <string>
using std::string;
#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class DerivedException1 definition
class DerivedException1 : public runtime_error
{
public:
// constructor specifies error message
DerivedException1::DerivedException1( const string& message )
: runtime_error( message ) {}
}; // end class DerivedException1

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Chapter 16 Exception Handling

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.26 Solution: DerivedException2.h


#include <string>
using std::string;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

// Exercise 16.26 Solution: Ex16_28.cpp


#include <iostream>
using std::cerr;
using std::endl;

#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class DerivedException2 definition
class DerivedException2 : public runtime_error
{
public:
// constructor specifies error message
DerivedException2::DerivedException2( const string& message )
: runtime_error( message ) {}
}; // end class DerivedException2

#include "DerivedException1.h"
#include "DerivedException2.h"
int main()
{
try // throw DerivedException1
{
throw ( DerivedException1( "DerivedException1" ) );
} // end try
catch ( runtime_error &exception ) // exceptions of runtime_error
{
cerr << exception.what() << endl;
} // end catch
try // throw DerivedException2
{
throw ( DerivedException2( "DerivedException2" ) );
} // end try
catch ( runtime_error &exception ) // exceptions of runtime_error
{
cerr << exception.what() << endl;
} // end catch
return 0;
} // end main

DerivedException1
DerivedException2

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises

16.27 Write a conditional expression that returns either a double or an int. Provide an int catch
handler and a double catch handler. Show that only the double catch handler executes, regardless
of whether the int or the double is returned.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// Exercise 16.27 Solution: Ex16_27.cpp


#include <iostream>
using std::cerr;
int main()
{
try // throw int
{
int a = 7;
double b = 9.9;
// throw int to show that only the double catch handler executes
throw a < b ? a : b;
} // end try
catch ( int x ) // catch ints
{
cerr << "The int value " << x << " was thrown\n";
} // end catch
catch ( double y ) // catch doubles
{
cerr << "The double value " << y << " was thrown\n";
} // end catch
return 0;
} // end main

The double value 7 was thrown

16.28 Write a program that generates and handles a memory-exhaustion exception. Your program
should loop on a request to create dynamic memory through operator new.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

// Exercise 16.28 Solution: Ex16_28.cpp


#include <iostream>
using std::cout;
using std::cerr;
#include <new>
using std::bad_alloc;
#include <cstdlib>
using std::exit;
int main()
{
long double *ptr[ 10 ];

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

8
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Chapter 16 Exception Handling

try // generate exception


{
// loop will cause memory exhaustion
for ( int i = 0; i < 10; i++ )
{
ptr[ i ] = new long double[ 50000000 ];
cout << "Allocated 50000000 long doubles in ptr[ " << i
<< " ]\n";
} // end for
} // end try
catch ( bad_alloc ex ) // catch bad_alloc exception
{
cerr << "Memory Allocation Failed.\n";
exit( EXIT_FAILURE );
} // end catch
return 0;
} // end main

Allocated 50000000 long doubles in ptr[ 0 ]


Allocated 50000000 long doubles in ptr[ 1 ]
Allocated 50000000 long doubles in ptr[ 2 ]
Memory Allocation Failed.

16.29 Write a program illustrating that all destructors for objects constructed in a block are called
before an exception is thrown from that block.
ANS:

1
2
3
4
5
6
7
8
9
10

// Exercise 16.29 Solution: TestObject.h


// Class TestObject definition.
class TestObject
{
public:
TestObject( int ); // constructor takes int parameter
~TestObject(); // destructor
private:
int value;
}; // end class TestObject

1
2
3
4
5
6
7
8
9
10

// Exercise 16.29 Solution: TestObject.cpp


// Class TestObject member function definition.
#include <iostream>
using std::cout;
#include "TestObject.h"
// constructor takes int parameter
TestObject::TestObject( int val ) : value( val )
{

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
11
12
13
14
15
16
17
18

cout << "TestObject " << value << " constructor\n";


} // end TestObject constructor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

// Exercise 16.29 Solution: Ex16_29.cpp


#include <iostream>
using std::cout;
using std::cerr;

// destructor
TestObject::~TestObject()
{
cout << "TestObject " << value << " destructor\n";
} // end TestObject destructor

#include <stdexcept>
using std::runtime_error;
#include "TestObject.h"
int main()
{
try // create objects and throw exception
{
// create three TestObjects
TestObject a( 1 );
TestObject b( 2 );
TestObject c( 3 );
cout << '\n';
// throw an exception to show that all three Objects created above
// will have their destructors called before the block expires
throw runtime_error( "This is a test exception" );
} // end try
// catch the Error
catch ( runtime_error &exception )
{
cerr << exception.what() << "\n";
} // end catch
return 0;
} // end main

TestObject 1 constructor
TestObject 2 constructor
TestObject 3 constructor
TestObject 3 destructor
TestObject 2 destructor
TestObject 1 destructor
This is a test exception

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

10

Chapter 16 Exception Handling

16.30 Write a program illustrating that member object destructors are called for only those member objects that were constructed before an exception occurred.
ANS:

1
2
3
4
5
6
7
8
9
10
11

// Exercise 16.30 Solution: Item.h


// Class Item definition.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// Exercise 16.30 Solution: Item.cpp


// Class Item member function definition.
#include <iostream>
using std::cout;

1
2
3
4
5
6
7
8
9

class Item
{
public:
Item( int ); // constructor takes int parameter
~Item(); // destructor
private:
int value;
}; // end class Item

#include <stdexcept>
using std::runtime_error;
#include "Item.h"
// constructor takes int parameter
Item::Item( int val ) : value( val )
{
cout << "Item " << value << " constructor called\n";
// if value is 3, throw an exception for demonstration purposes
if ( value == 3 )
throw runtime_error( "An exception was thrown" );
} // end Items constructor
// destructor
Item::~Item()
{
cout << "Item " << value << " destructor called\n";
} // end Items destructor

// Exercise 16.30 Solution: ItemGroup.h


// Class ItemGroup definition.
#include "Item.h"
class ItemGroup
{
public:
ItemGroup(); // constructor
~ItemGroup(); // destructor

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
10
11
12
13
14
15
16

private:
Item item1;
Item item2;
Item item3;
Item item4;
Item item5;
}; // end class ItemGroup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

// Exercise 16.30 Solution: ItemGroup.cpp


// Class ItemGroup member function definition.
#include <iostream>
using std::cout;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// Exercise 16.30 Solution: Ex16_30.cpp


#include <iostream>
using std::cout;
using std::cerr;

#include "ItemGroup.h"
// constructor
ItemGroup::ItemGroup()
: item1( 1 ), item2( 2 ), item3( 3 ), item4( 4 ), item5( 5 )
{
cout << "ItemGroup constructor called\n";
} // end ItemGroup constructor
// destructor
ItemGroup::~ItemGroup()
{
cout << "ItemGroup destructor called\n";
} // end ItemGroup destructor

#include <stdexcept>
using std::runtime_error;
#include "ItemGroup.h"
int main()
{
cout << "Constructing an object of class ItemGroup\n";
try // create ItemGroup object
{
ItemGroup itemGroup;
} // end try
catch( runtime_error &exception )
{
cout << exception.what() << '\n';
} // end catch

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

11

12
24
25

Chapter 16 Exception Handling

return 0;
} // end main

Constructing an object of class ItemGroup


Item 1 constructor called
Item 2 constructor called
Item 3 constructor called
Item 2 destructor called
Item 1 destructor called
An exception was thrown

16.31 Write a program that demonstrates several exception types being caught with the
catch(...) exception handler.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.31 Solution: TestException1.h


#include <string>
using std::string;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.31 Solution: TestException2.h


#include <string>
using std::string;

1
2
3

#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class TestException1 definition
class TestException1 : public runtime_error
{
public:
// constructor specifies error message
TestException1::TestException1()
: runtime_error( "TestException1" ) {}
}; // end class TestException1

#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class TestException2 definition
class TestException2 : public runtime_error
{
public:
// constructor specifies error message
TestException2::TestException2()
: runtime_error( "TestException2" ) {}
}; // end class TestException2
// Exercise 16.31 Solution: Ex16_31.cpp
#include <iostream>
using std::cout;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

13

using std::cerr;
#include <ctime> // prototype for time
using std::time;
#include <cstdlib> // prototypes for srand and rand
using std::rand;
using std::srand;
#include "TestException1.h"
#include "TestException2.h"
void generateException();
int main()
{
srand( time( 0 ) ); // using current time to randomize random number
// loop 5 times to generate various exceptions
for ( int i = 0; i < 5; i++ )
{
try // generate exception
{
generateException();
} // end try
catch( ... )
{
cerr << "The \"catch all\" exception handler was invoked\n";
} // end catch
} // end for
return 0;
} // end main
// throw exception randomly
void generateException()
{
int type = 1 + rand() % 3;
TestException1 exception1;
TestException2 exception2;
switch( type )
{
case 1: // throw int exception
cout << "\nThrowing exception of type int...\n";
throw( 10 );
case 2: // throw TestException1
cout << "\nThrowing exception of type TestException1...\n";
throw( exception1 );
case 3: // throw TestException2
cout << "\nThrowing exception of type TestException2...\n";
throw( exception2 );
} // end switch
} // end function generateException

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

14

Chapter 16 Exception Handling

Throwing exception of type TestException2...


The "catch all" exception handler was invoked
Throwing exception of type TestException1...
The "catch all" exception handler was invoked
Throwing exception of type TestException2...
The "catch all" exception handler was invoked
Throwing exception of type TestException1...
The "catch all" exception handler was invoked
Throwing exception of type int...
The "catch all" exception handler was invoked

16.32 Write a program illustrating that the order of exception handlers is important. The first
matching handler is the one that executes. Attempt to compile and run your program two different
ways to show that two different handlers execute with two different effects.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.32 Solution: TestException.h


#include <string>
using std::string;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

// Exercise 16.32 Solution: Ex16_32_a.cpp


#include <iostream>
using std::cout;
using std::endl;

#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class TestException definition
class TestException : public runtime_error
{
public:
// constructor specifies error message
TestException::TestException( const string& message )
: runtime_error( message ) {}
}; // end class TestException

#include "TestException.h"
int main()
{
try // throw TestException
{
// throw an exception of the derived class
throw TestException( "This is a TestException" );
} // end try
catch ( runtime_error &exception ) // catch runtime_error exception
{

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
17
18
19
20
21
22
23
24
25

15

cout << "runtime_error was caught\n" << exception.what() << endl;


} // end catch
catch ( TestException &exception ) // catch TestException
{
cout << "TestException was caught\n" << exception.what() << endl;
} // end catch
return 0;
} // end main

runtime_error was caught


This is a TestException

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// Exercise 16.32 Solution: Ex16_32_b.cpp


#include <iostream>
using std::cout;
using std::endl;
#include "TestException.h"
int main()
{
try // throw TestException
{
// throw an exception of the derived class
throw TestException( "This is a TestException" );
} // end try
catch ( TestException &exception ) // catch TestException
{
cout << "TestException was caught\n" << exception.what() << endl;
} // end catch
catch ( runtime_error &exception ) // catch runtime_error exception
{
cout << "runtime_error was caught\n" << exception.what() << endl;
} // end catch
return 0;
} // end main

TestException was caught


This is a TestException

16.33 Write a program that shows a constructor passing information about constructor failure to
an exception handler after a try block.
ANS:

1
2
3

// Exercise 16.33 Solution: InvalidIDException.h


#include <string>
using std::string;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

16
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9

Chapter 16 Exception Handling

#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class InvalidIDException definition
class InvalidIDException : public runtime_error
{
public:
// constructor specifies error message
InvalidIDException::InvalidIDException( const string &message )
: runtime_error( message ) {}
}; // end class InvalidIDException

// Exercise 16.33 Solution: IDObject.h


class IDObject
{
public:
IDObject( int ); // constructor
private:
int idNumber;
}; // end class IDObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.33 Solution:IDObject.cpp


#include <iostream>
using std::cout;

1
2
3
4
5
6
7
8
9
10
11

// Exercise 16.33 Solution: Ex16_33.cpp


#include <iostream>
using std::cerr;

#include "IDObject.h"
#include "InvalidIDException.h"
// constructor takes an int
IDObject::IDObject( int id ) : idNumber( id )
{
cout << "Constructor for IDObject " << idNumber << '\n';
if ( idNumber < 0 ) // negative id
throw InvalidIDException( "ERROR: Negative ID number" );
} // end IDObject constructor

#include "IDObject.h"
#include "InvalidIDException.h"
int main()
{
try // create two IDObjects
{

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
12
13
14
15
16
17
18
19
20
21

17

IDObject valid( 10 ); // valid id


IDObject invalid( -1 ); // invalid id, will throw an exception
} // end try
catch ( InvalidIDException &exception ) // catch InvalidIDException
{
cerr << exception.what() << '\n';
} // end catch
return 0;
} // end main

Constructor for IDObject 10


Constructor for IDObject -1
ERROR: Negative ID number

16.34 Write a program that illustrates rethrowing an exception.


ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.34 Solution: TestException.h


#include <string>
using std::string;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

// Exercise 16.34 Solution: Ex16_34.cpp


#include <iostream>
using std::cout;
using std::cerr;

#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class TestException definition
class TestException : public runtime_error
{
public:
// constructor specifies error message
TestException::TestException( const string& message )
: runtime_error( message ) {}
}; // end class TestException

#include "TestException.h"
// function f throws a TestException
void f()
{
throw TestException( "Test exception thrown" );
} // end function f
// function g calls function f
// and rethrows any exception thrown from f
void g()

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

18
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

Chapter 16 Exception Handling

try
{
f();
} // end try
catch ( ... ) // catch any exception and rethrow it
{
cerr << "Exception caught in function g(). Rethrowing...\n";
throw;
} // end catch
} // end function g
int main()
{
try
{
g(); // start function call chain
} // end try
catch ( ... ) // catch any exception thrown from g
{
cerr << "Exception caught in function main()\n";
} // end catch
return 0;
} // end main

Exception caught in function g(). Rethrowing...


Exception caught in function main()

16.35 Write a program that illustrates that a function with its own try block does not have to
catch every possible error generated within the try. Some exceptions can slip through to, and be
handled in, outer scopes.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.35 Solution: TestException1.h


#include <string>
using std::string;
#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class TestException1 definition
class TestException1 : public runtime_error
{
public:
// constructor specifies error message
TestException1::TestException1( const string &message )
: runtime_error( message ) {}
}; // end class TestException1

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.35 Solution: TestException2.h


#include <string>
using std::string;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

// Exercise 16.35 Solution: Ex16_35.cpp


#include <iostream>
using std::cout;
using std::cerr;

#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class TestException2 definition
class TestException2 : public runtime_error
{
public:
// constructor specifies error message
TestException2::TestException2( const string &message )
: runtime_error( message ) {}
}; // end class TestException2

#include "TestException1.h"
#include "TestException2.h"
void f()
{
throw TestException1( "TestException1" );
} // end function f
void g()
{
try
{
f();
} // end try
catch ( TestException2 &t2 ) // catch TestException2
{
cerr << "In g: Caught " << t2.what() << '\n';
} // end catch
} // end function g
int main()
{
try
{
g();
} // end try
catch ( TestException1 &t1 ) // catch TestException1
{
cerr << "In main: Caught " << t1.what() << '\n';
} // end catch

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

19

20
37
38

Chapter 16 Exception Handling

return 0;
} // end main

In main: Caught TestException1

16.36 Write a program that throws an exception from a deeply nested function and still has the
catch handler following the try block enclosing the call chain catch the exception.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 16.36 Solution: TestException.h


#include <string>
using std::string;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// Exercise 16.36 Solution: Ex16_36.cpp


#include <iostream>
using std::cout;
using std::cerr;

#include <stdexcept>
using std::runtime_error; // standard C++ library class runtime_error
// class TestException definition
class TestException : public runtime_error
{
public:
// constructor specifies error message
TestException::TestException( const string& message )
: runtime_error( message ) {}
}; // end class TestException

#include "TestException.h"
void f()
{
throw TestException( "TestException" );
} // end function f
void g() { f(); } // end function g
void h() { g(); } // end function h
int main()
{
try
{
h();
} // end try
catch ( TestException &t ) // catch any exceptions that occurred in h
{
cerr << "In main: Caught " << t.what() << \n;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercises
26
27
28
29

} // end catch
return 0;
} // end main

In main: Caught TestException

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

21