Consider the following text:
[C++11: 12.4/11]:Destructors are invoked implicitly
- for constructed objects with static
The first part is not ill-formed because the standard text doesn't apply - no object of type A is declared there.
For the second part, let's review how object construction works. The standard says (15.2/2) that if any part of construction throws, all fully constructed subobjects up to that point are destroyed in reverse order of construction.
This means that the code underlying a constructor, if all written out by hand, would look something like this:
// Given:
struct C : A, B {
D d;
C() : A(), B(), d() { /* more code */ }
};
// This is the expanded constructor:
C() {
A();
try {
B();
try {
d.D();
try {
/* more code */
} catch(...) { d.~D(); throw; }
} catch(...) { ~B(); throw; }
} catch(...) { ~A(); throw; }
}
For your simpler class, the expanded code for the default constructor (whose definition is required by the new expression) would look like this:
B::B() {
A();
try {
// nothing to do here
} catch(...) {
~A(); // error: ~A() is deleted.
throw;
}
}
Making this work for cases where no exception can possibly be thrown after initialization for some subobject has been completed is just too complex to specify. Therefore, this doesn't actually happen, because the default constructor for B is implicitly defined as deleted in the first place, due to the last bullet point in N3797 12.1/4:
A defaulted default constructor for class X is defined as deleted if:
- [...]
- any direct or virtual base class or non-static data member has a type with a destructor that is deleted or inaccessible from the defaulted default constructor.
The equivalent language exists for copy/move constructors as the fourth bullet in 12.8/11.
There is also an important paragraph in 12.6.2/10:
In a non-delegating constructor, the destructor for each direct or virtual base class and for each non-static data member of class type is potentially invoked.