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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…