Online Book Reader

Home Category

Professional C__ - Marc Gregoire [167]

By Root 1057 0
constructor, and assignment operator, as described in Chapter 7.

Objects thrown as exceptions are always copied by value at least once.

It is possible for exceptions to be copied more than once, but only if you catch the exception by value instead of by reference.

Catch exception objects by reference to avoid unnecessary copying.

Nested Exceptions

It could happen that during handling of a first exception, a second exceptional situation is triggered which requires a second exception to be thrown. Unfortunately, when you throw the second exception, all information about the first exception that you are currently trying to handle will be lost. C++11 provides a solution to this problem with the concept of nested exceptions, which allow you to nest a caught exception in the context of a new exception. To that end, a mix-in class called std::nested_exception is provided which captures and stores a copy of the exception currently being processed. A catch handler for the second exception can use a dynamic_cast to get access to the nested_exception representing the first exception. The following example will demonstrate the use of nested exceptions. The first thing you need to do is to define your own exception class and at least inherit from the nested_exception mix-in class. This example defines a MyException class which derives from exception and from the mix-in class nested_exception. It also accepts a string in its constructor.

class MyException : public std::exception, public std::nested_exception

{

public:

MyException(const char* msg) : mMsg(msg) {}

virtual ~MyException() noexcept {}

virtual const char* what() const noexcept { return mMsg.c_str(); }

protected:

std::string mMsg;

};

Code snippet from NestedException\NestedException.cpp

When you are handling a first exception and you need to throw a second exception with the first one nested inside it, you need to use the std::throw_with_nested() function. This function requires as parameter an instance of a class that inherits from nested_exception, like the MyException class in this example. The following doSomething() function throws a runtime_error which is immediately caught in the catch handler. The catch handler writes a message and then uses the throw_with_nested() function to throw a second exception that has the first one nested inside it. Note that nesting the exception inside the MyException instance happens automatically due to the nested_exception mix-in class.

void doSomething()

{

try {

throw std::runtime_error("Throwing a runtime_error exception");

} catch (const std::runtime_error& e) {

std::cout << __func__ << " caught a runtime_error" << std::endl;

std::cout << __func__ << " throwing MyException" << std::endl;

std::throw_with_nested(

MyException("MyException with nested runtime_error"));

}

}

Code snippet from NestedException\NestedException.cpp

The following main() function demonstrates how to handle the exception with a nested exception. The code calls the doSomething() function and has one catch handler for exceptions of type MyException. When it catches such an exception, it writes a message and then uses a dynamic_cast to get access to the nested exception. If there is no nested exception inside, the result will be a null pointer. If there is a nested exception inside, the rethrow_nested() method on the nested_exception is called. This will cause the nested exception to be rethrown which you can then catch in another try/catch block.

int main()

{

try {

doSomething();

} catch (const MyException& e) {

std::cout << __func__ << " caught MyException: " << e.what()

<< std::endl;

const std::nested_exception* pNested =

dynamic_cast(&e);

if (pNested) {

try {

pNested->rethrow_nested();

} catch (const std::runtime_error& e) {

// Handle nested exception

std::cout << " Nested exception: " << e.what()

<< std::endl;

}

}

}

return 0;

}

Code snippet from NestedException\NestedException.cpp

The output should be as follows:

doSomething caught a runtime_error

doSomething throwing

Return Main Page Previous Page Next Page

®Online Book Reader