    Object destructors are only activated for completely constructed objects.
Although this may
sound like a truism, there is a subtlety here. If the construction of an
object fails for some reason, the object's destructor is em(not) called when
the object goes out of scope. This could happen if an exception that is
 hi(exception: and constructors)hi(constructor: and exceptions)
    generated by the constructor is not caught by the constructor. If the
exception is thrown when the object has already allocated some memory, then
that memory is not returned: its destructor isn't called as the object's
construction wasn't successfully completed.

    The following example illustrates this situation in its prototypical
form. The constructor of the class tt(Incomplete) first displays a message
and then throws an exception. Its destructor also displays a message:
        verbinclude(//INCOMPLETE examples/constructor.cc)
    Next, tt(main()) creates an tt(Incomplete) object inside a tt(try)
block. Any exception that may be generated is subsequently caught:
        verbinclude(//MAIN examples/constructor.cc)
    When this program is run, it produces the following output:
        verb(
    Creating `Incomplete' object
    Allocated some memory
    Caught exception
        )
    Thus, if tt(Incomplete)'s constructor would actually have allocated some
memory, the program would suffer from a memory leak. To prevent this from
happening, the following counter measures are available:
    itemization(
    it() Prevent the exceptions from leaving the constructor.nl()
        If part of the constructor's body may generate exceptions, then this
part may be surrounded by a tt(try) block, allowing the exception to be caught
by the constructor itself. This approach is defensible when the constructor
is able to repair the cause of the exception and to complete its construction
as a valid object.
    it() If an exception is generated by a base class constructor or by a
member initializing constructor then a tt(try) block within the constructor's
 body won't be able to catch the thrown exception. This em(always) results in
the exception leaving the constructor and the object is not considered to have
been properly constructed. A tt(try) block may include the member
initializers, and the tt(try) block's compound statement becomes the
constructor's body as in the following example:
    verb(
class Incomplete2
{
    Composed d_composed;
    public:
        Incomplete2()
        try
        :
            d_composed(/* arguments */)
        {
            // body
        }
        catch (...)
        {}
};
        )
    An exception thrown by either the member initializers or the body
results in the execution never reaching the body's closing curly brace. Instead
the catch clause is reached. Since the constructor's body isn't properly
completed the object is not considered properly constructed and eventually the
object's destructor won't be called.
    )
    The catch clause of a constructor's function tt(try) block behaves
slightly different than a catch clause of an ordinary function tt(try)
block. An exception reaching a constructor's function tt(try) block may be
transformed into another exception (which is thrown from the catch clause) but
if no exception is explicitly thrown from the catch clause the exception
originally reaching the catch clause is always rethrown. Consequently, there's
no way to confine an exception thrown from a base class constructor or from a
member initializer to the constructor: such an exception em(always) propagates
to a more shallow block and in that case the object's construction is always
considered incomplete.

    Consequently, if incompletely constructed objects throw exceptions then
the constructor's catch clause is responsible for preventing memory
(generally: resource) leaks. There are several ways to realize this:
    itemization(
    it() When multiple inheritance is used: if initial base classes have
properly been constructed and a later base class throws, then the initial base
class objects are automatically destroyed (as they are themselves fully
constructed objects)
    it() When composition is used: already constructed composed objects are
automatically destroyed (as they are fully constructed objects)
    it() Instead of using plain pointers em(smart pointers) (cf. section
ref(SHAREDPTR)) should be used to manage dynamically allocated memory. In this
case, if the constructor throws either before or after the allocation of the
dynamic memory, then allocated memory is properly returned as tt(shared_ptr)
objects are, after all, objects.
    it() If plain pointer data members em(must) be used then the constructor's
body should first, in its member initialization section, initialize its plain
pointer data members. Then, in its body it can dynamically allocate memory,
reassigning the plain pointer data members. The constructor must be provided
with a function try block whose generic catch clause deletes the memory
pointed at by the class's plain pointer data members. Example:
    verb(
class Incomplete2
{
    Composed d_composed;
    char *d_cp;         // plain pointers
    int *d_ip;

    public:
        Incomplete2(size_t nChars, size_t nInts)
        try
        :
            d_composed(/* arguments */),    // might throw
            d_cp(0),
            d_ip(0)
        {
            preamble();                     // might throw
            d_cp = new char[nChars];        // might throw
            d_ip = new int[nChars];         // might throw
            postamble();                    // might throw
        }
        catch (...)
        {
            delete[] d_cp;                  // clean up
            delete[] d_ip;
        }
};
        )
    )

    On the other hand, since bf(C++) supports constructor delegation an object
may have been completely constructed according to the bf(C++) run-time system,
but yet its constructor may have thrown an exception. This happens if a
delegated constructor successfully completes (after which the object is
considered `completely constructed'), but the constructor itself throws an
exception, as illustrated by the next example:
        verb(
    class Delegate
    {
        public:
            Delegate()
            :
                Delegate(0)
            {
                throw 12;       // throws but completely constructed
            }
            Delegate(int x)         // completes OK
            {}
    };
    int main()
    try
    {
        Delegate del;           // throws

    } // del's destructor is called here
    catch (...)
    {}
        )
    In this example it is the responsibility of tt(Delegate)'s designer to
ensure that the throwing default constructor does not invalidate the actions
performed by tt(Delegate)'s destructor. E.g., if the delegated constructor
allocates memory to be deleted by the destructor, then the default constructor
should either leave the memory as-is, or it can delete the memory and set the
corresponding pointer to zero thereafter. In any case, it is tt(Delegate)'s
responsibility to ensure that the object remains in a valid state, even though
it throws an exception.

    According to the bf(C++) standard exceptions thrown by destructors may not
leave their bodies. Providing a destructor with a function tt(try) block is
therefore a violation of the standard: exceptions caught by a function tt(try)
block's catch clause have already left the destructor's body.  If --in
violation of the standard-- the destructor em(is) provided with a function
tt(try) block and an exception is caught by the tt(try) block then that
exception is rethrown, similar to what happens in catch clauses of
constructor functions' tt(try) blocks.

The consequences of  an exception leaving the destructor's body is not
defined, and may result in unexpected behavior. Consider the following example:

Assume a carpenter builds a cupboard having a single drawer. The cupboard
is finished, and a customer, buying the cupboard, finds that the cupboard can
be used as expected. Satisfied with the cupboard, the customer asks the
carpenter to build another cupboard, this time having em(two)
drawers. When the second cupboard is finished, the customer takes it home and
is utterly amazed when the second cupboard completely collapses immediately
after it is used for the first time.

    Weird story? Then consider the following program:
        verbinclude(//MAIN examples/destructor.cc)
    When this program is run it produces the following output:
        verb(
    Creating Cupboard1
    Drawer 1 used
    Cupboard1 behaves as expected
    Creating Cupboard2
    Drawer 2 used
    Drawer 1 used
    terminate called after throwing an instance of 'int'
    Abort
        )
    The final tt(Abort) indicates that the program has aborted instead of
displaying a message like tt(Cupboard2 behaves as expected).

Let's have a look at the three classes involved. The class tt(Drawer) has no
particular characteristics, except that its destructor throws an exception:
        verbinclude(//DRAWER examples/destructor.cc)
    The class tt(Cupboard1) has no special characteristics at all. It merely
has a single composed tt(Drawer) object:
        verbinclude(//CUP1 examples/destructor.cc)
    The class tt(Cupboard2) is constructed comparably, but it has two
composed tt(Drawer) objects:
        verbinclude(//CUP2 examples/destructor.cc)

    When tt(Cupboard1)'s destructor is called tt(Drawer)'s destructor is
eventually called to destroy its composed object. This destructor throws an
exception, which is caught beyond the program's first tt(try) block. This
behavior is completely as expected.

A subtlety here is that tt(Cupboard1)'s destructor (and hence tt(Drawer)'s
destructor) is activated em(immediately) subsequent to its construction. Its
destructor is called immediately subsequent to its construction as
tt(Cupboard1()) defines an anonymous object. As a result the tt(Beyond
Cupboard1 object) text is never inserted into tt(std::cerr).

    Because of tt(Drawer)'s destructor throwing an exception a problem occurs
when tt(Cupboard2)'s destructor is called. Of its two composed objects, the
second tt(Drawer)'s destructor is called first.  This destructor throws an
exception, which ought to be caught beyond the program's second tt(try)
block. However, although the flow of control by then has left the context of
tt(Cupboard2)'s destructor, that object hasn't completely been destroyed yet
as the destructor of its other (left) tt(Drawer) still has to be called.

    Normally that would not be a big problem: once an exception is thrown from
tt(Cupboard2)'s destructor any remaining actions would simply be ignored,
albeit that (as both drawers are properly constructed objects) tt(left)'s
destructor would still have to be called.

    This happens here too and tt(left)'s destructor em(also) needs to throw an
exception. But as we've already left the context of the second tt(try) block,
the current flow control is now thoroughly mixed up, and the program has no
other option but to abort. It does so by calling tt(terminate()), which in
turn calls tt(abort()). Here we have our collapsing cupboard having two
drawers, even though the cupboard having one drawer behaves perfectly.

    The program aborts since there are multiple composed objects whose
destructors throw exceptions leaving the destructors. In this situation one of
the composed objects would throw an exception by the time the program's flow
control has already left its proper context causing the program to abort.

    The bf(C++) standard therefore understandably stipulates that exceptions
may em(never) leave destructors. Here is the skeleton of a destructor whose
 hi(destructor: and exceptions)hi(exception: and destructors) code might throw
exceptions. No function tt(try) block but all the destructor's actions are
encapsulated in a tt(try) block nested under the destructor's body.
        verb(
    Class::~Class()
    {
        try
        {
            maybe_throw_exceptions();
        }
        catch (...)
        {}
    }
        )
