16.9. Constructors, Destructors and
Exception Handling
First, let's discuss an issue that we
have mentioned but not yet resolved satisfactorily: What happens when an error
is detected in a constructor? For example, how should an object's constructor
respond when new fails because it was unable
to allocate required memory for storing that object's internal representation?
Because the constructor cannot return a value to indicate an error, we must
choose an alternative means of indicating that the object has not been
constructed properly. One scheme is to return the improperly constructed object
and hope that anyone using it would make appropriate tests to determine that it
is in an inconsistent state. Another scheme is to set some variable outside the
constructor. The preferred alternative is to require the constructor to
throw an exception that contains the error
information, thus offering an opportunity for the program to handle the
failure.
Before an exception is thrown by a
constructor, destructors are called for any member objects built as part of the
object being constructed. Destructors are called for every automatic object
constructed in a try block before an
exception is thrown. Stack unwinding is guaranteed to have been completed at the
point that an exception handler begins executing. If a destructor invoked as a
result of stack unwinding throws an exception, terminate is called.
If an object has member objects,
and if an exception is thrown before the outer object is fully constructed, then
destructors will be executed for the member objects that have been constructed
prior to the occurrence of the exception. If an array of objects has been
partially constructed when an exception occurs, only the destructors for the
constructed objects in the array will be called.
An exception could preclude the
operation of code that would normally release a resource, thus causing a
resource leak. One technique to resolve this problem is to initialize a local
object to acquire the resource. When an exception occurs, the destructor for
that object will be invoked and can free the resource.
Error-Prevention Tip 16.4
|
When an
exception is thrown from the constructor for an object that is created in a
new expression, the dynamically allocated memory for that object is
released. |