In GMan's answer here, the destructor of the restore_base
class isn't virtual
, so I keep wondering how exactly that works. Normally you'd expect the destructor of restorer_base
to be executed only, after the object goes out of scope, but it seems that the derived restorer_holder
destructor is really called. Anyone care to enlighten me?
The standard case where you need a virtual destructor is
void foo()
{
scoped_ptr<Base> obj = factory_returns_a_Derived();
// ... use 'obj' here ...
}
And the standard case where you don't is
void foo()
{
Derived obj;
// ... use 'obj' here ...
}
GMan's code is doing something a little trickier, that turns out to be equivalent to the second case:
void foo()
{
Base& obj = Derived();
// ... use 'obj' here ...
}
obj
is a bare reference; normally, it would not trigger destructors at all. But it's initialized from an anonymous temporary object whose static type -- known to the compiler -- is Derived
. When that object's lifetime ends, the compiler will call the Derived
destructor. Normally an anonymous temporary object dies at the end of the expression that created it, but there's a special case for temporaries initializing a reference: they live till the reference itself dies, which here is the end of the scope. So you get pseudo-scoped_ptr
behavior and you don't need a virtual destructor.
EDIT: Since this has now come up twice: The reference does not have to be const
for this special rule to apply. C+98 [class.temporary]/5:
The second context [in which a temporary object is not destroyed at the end of the full-expression] is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference ...
Emphasis mine. There is no mention of const
in this language, so the reference does not have to be const
.
EDIT 2: Other rules in the standard prohibit creation of non-const references to temporary objects that are not lvalues. I suspect that at least some temporary objects are lvalues, but I don't know for certain. Regardless, that does not affect this rule. It would still be formally true that non-const references to temporary objects prolong their lifetime even if no strictly conforming C++ program could ever create such a reference. This might seem ridiculous, but you're supposed to read standardese this literally and pedantically. Every word counts, every word that isn't there counts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With