Subobjects (including non-static data members) have the same storage duration as the complete objects to which they belong. This is not the same as saying that they are automatic. An automatic object is destroyed at the end of a block. A subobject is destroyed whenever its complete object is destroyed. For example, if the complete object is created with new
and destroyed with delete
(i.e. has dynamic storage duration), then the subobject is also created in the call to new
, and destroyed in the call to delete
. On the other hand, a subobject of an automatic object is also automatic.
If the constructor for X::bb
throws an exception, then it means the complete object of type X
cannot be constructed. All subobjects that have already been constructed, such as X::aa
, must be destroyed, because a subobject, having the same storage duration as its complete object, cannot survive without the complete object.
On the other hand, if construction of the entire X
object completes successfully, X::aa
and other subobjects won't be destroyed until (shortly after) the complete X
object is destroyed.
The construction and destruction rules for C++ are intended to guarantee that, as long as a program terminates normally, every object that is created is also destroyed exactly once. This is essential for the RAII idiom. In this example, if X::aa
acquires resources when it is constructed, the language must ensure that those resources will be released. If X::aa
's destructor is not called when construction of the X
fails, then when should it be called?