Online Book Reader

Home Category

Professional C__ - Marc Gregoire [158]

By Root 1102 0
as follows:

return !fail();

If the >> operator encounters an error, it will set the fail bit of the ifstream object. In that case, the bool() conversion operator will return false and the while loop will terminate. Streams are discussed in more detail in Chapter 15.

You might use readIntegerFile() like this:

vector myInts;

const string fileName = "IntegerFile.txt";

readIntegerFile(fileName, myInts);

for (size_t i = 0; i < myInts.size(); i++) {

cout << myInts[i] << " ";

}

cout << endl;

Code snippet from ReadIntegerFile\NoExceptionHandling.cpp

The lack of error handling in these functions should jump out at you. The rest of this section shows you how to add error handling with exceptions.

Throwing and Catching Exceptions

Using exceptions consists of providing two parts in your program: a try/catch construct, to handle an exception, and a throw statement, that throws an exception. Both must be present in some form to make exceptions work. However, in many cases, the throw happens deep inside some library (including the C++ run time) and the programmer never sees it, but still has to react to it using a try/catch construct.

The try/catch construct looks as follows:

try {

// ... code which may result in an exception being thrown

} catch (exception-type1 exception-name) {

// ... code which responds to the exception of type 1

} catch (exception-type2 exception-name) {

// ... code which responds to the exception of type 2

}

// ... remaining code

The code which may result in an exception being thrown might contain a throw directly, or might be calling a function which either directly throws an exception or calls, by some unknown number of layers of calls, a function which throws an exception.

If no exception is thrown, the code in the catch blocks is not executed, and the “remaining code” which follows will follow the last statement executed in the try block.

If an exception is thrown, any code following the throw or following the call which resulted in the throw, is not executed, but control immediately goes to the right catch block depending on the type of the exception that is thrown.

If the catch block does not do a control transfer, for example by returning a value, throwing a new exception or rethrowing the exception, then the “remaining code” is executed after the last statement of that catch block.

The simplest example to demonstrate exception handling is avoiding divide-by-zero. This example throws an exception of type invalid_argument which requires the header.

int SafeDivide(int num, int den)

{

if (den == 0)

throw invalid_argument("Divide by zero");

return num / den;

}

int main()

{

try {

cout << SafeDivide(5, 2) << endl;

cout << SafeDivide(10, 0) << endl;

cout << SafeDivide(3, 3) << endl;

} catch (const invalid_argument& e) {

cout << "Caught exception: " << e.what() << endl;

}

return 0;

}

Code snippet from SafeDivide\SafeDivide.cpp

The output is as follows:

2

Caught exception: Divide by zero

throw is a keyword in C++, and is the only way to throw an exception. The invalid_argument() part of the throw line means that you are constructing a new object of type invalid_argument to throw.

The throw keyword can also be used to rethrow the current exception. For example:

void g() { throw 2; }

void f()

{

try {

g();

} catch (int i) {

cout << "caught in f: " << i << endl;

throw; // rethrow

}

}

int main()

{

try {

f();

} catch (int i) {

cout << "caught in main: " << i << endl;

}

return 0;

}

Code snippet from Rethrow\rethrow.cpp

This example produces the following output:

caught in f: 2

caught in main: 2

Let’s go back to the readIntegerFile() function. The most likely problem to occur is for the file open to fail. That’s a perfect situation for throwing an exception. This code throws an exception of type exception which requires the header. The syntax looks like this:

#include

void readIntegerFile(const string& fileName, vector& dest)

{

ifstream istr;

int temp;

istr.open(fileName.c_str());

if (istr.fail())

Return Main Page Previous Page Next Page

®Online Book Reader