Online Book Reader

Home Category

Professional C__ - Marc Gregoire [172]

By Root 1329 0
mMatrix;

mMatrix = nullptr;

}

Code snippet from ConstructorError\Matrix.cpp

Remember, if an exception leaves a constructor, the destructor for that object will never be called!

You might be wondering what happens when you add inheritance into the mix. Superclass constructors run before subclass constructors. If a subclass constructor throws an exception, how are the resources that the superclass constructor allocated freed?

C++ guarantees that it will run the destructor for any fully constructed “subobjects.” Therefore, any constructor that completes without an exception will cause the corresponding destructor to be run.

Function-Try-Blocks for Constructors

The exception mechanism as discussed up to now in this chapter is perfect to handle exceptions within functions. However, how should you handle exceptions thrown from inside a ctor-initializer of a constructor? This section explains a feature called function-try-blocks, which are capable of catching those exceptions. Most C++ programmers, even experienced C++ programmers don’t know the existence of this feature, even though it was introduced more than a decade ago.

The following piece of pseudo code shows the basic syntax for a function-try-block for a constructor:

MyClass::MyClass()

try

:

{

/* ... constructor body ... */

}

catch (const exception& e)

{

/* ... */

}

As you can see, the try keyword should be right before the start of the ctor-initializer. The catch statements should be after the closing brace for the constructor, actually putting them outside the constructor body. There are a number of restrictions and guidelines that you should keep in mind when using function-try-blocks with constructors:

The catch statements will catch any exception either thrown directly or indirectly by the ctor-initializer or by the constructor body.

The catch statements have to rethrow the current exception or throw a new exception. If a catch statement doesn’t do this, the run time will automatically rethrow the current exception.

When a catch statement catches an exception in a function-try-block, all objects that have already been constructed by the constructor will be destroyed before execution of the catch statement starts.

You should not access member variables for the object inside a function-try-block catch statement.

The catch statements in a function-try-block cannot use the return keyword to return a value from the function enclosed by it. This is not relevant for constructors because they do not return anything.

Based on this list of limitations, function-try-blocks for constructors are useful only in a very limited number of situations:

To convert an exception thrown by the ctor-initializer to another exception.

To log a message to a log file.

Let’s see how to use function-try-blocks with an example. The following code defines a class called SubObject. It has only one constructor, which throws an exception of type runtime_error.

class SubObject

{

public:

SubObject(int i) throw(std::runtime_error);

};

SubObject::SubObject(int i) throw(std::runtime_error)

{

throw std::runtime_error("Exception by SubObject ctor");

}

Code snippet from FunctionTryBlock\FunctionTryBlocks.cpp

The MyClass class has a member variable of type SubObject:

class MyClass

{

public:

MyClass() throw(std::runtime_error);

protected:

SubObject mSubObject;

};

Code snippet from FunctionTryBlock\FunctionTryBlocks.cpp

The SubObject class does not have a default constructor. This means that you need to initialize mSubObject in the MyClass ctor-initializer. The constructor of the MyClass class will use a function-try-block to catch exceptions thrown in its ctor-initializer:

MyClass::MyClass() throw(std::runtime_error)

try

: mSubObject(42)

{

/* ... constructor body ... */

}

catch (const std::exception& e)

{

cout << "function-try-block caught: '" << e.what() << "'" << endl;

}

Code snippet from FunctionTryBlock\FunctionTryBlocks.cpp

Remember that catch statements in a function-try-block for a constructor have to

Return Main Page Previous Page Next Page

®Online Book Reader