The answer is... nearly always.
If your object has a non-virtual destructor, and is then sub-classed to add child elements that need freeing... then calling the destructor on the object base class will not free the child elements. This is why you should always declare destructors virtual.
We had an interesting case where two shared libraries referenced an object. We changed the definition to add child objects which needed freeing. We recompiled the first shared library which contained the object definition.
HOWEVER, the second shared library was not recompiled. This means that it did not know of the newly added virtual object definition. Delete's invoked from the second shared library simply called free, and did not invoke the virtual destructor chain. Result was a nasty memory leak.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…