Every abstract class should either have a,
- protected destructor, or,
- virtual destructor.
If you’ve got a public non-virtual destructor, that’s no good, since it allows users to delete through that pointer a derived object. Since as we all know, that’s undefined behavior.
For an abstract class, you already need a virtual-table pointer in the object, so making the destructor virtual
doesn’t (as far as I’m aware) have a high cost in terms of space or runtime performance. And it has the benefit that derived classes automatically have their destructors virtual
(see @Aconcagua’s comment). Of course, you can also make the destructor protected virtual
for this case.
For a non-abstract class not intended to be deleted through a pointer to it, I don’t think there’s good reason to have a virtual destructor. It would waste resources, but more importantly it would give users a wrong hint. Just think about what weird sense it would make to give std::iterator
a virtual destructor.