Constructors, Destructors and Exception Handling
First, let us 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. Perhaps the best 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.
Exceptions thrown by a constructor cause destructors to be called for any objects built as part of the object being constructed before the exception is thrown. 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. |