13
votes

Destructors aren't virtual by default to not hurt when its not needed, which is fine.

But in case of a base class derived class scenario, is there any use case for not having a virtual destructor? If not could it be possible (does it make sense) for the compiler to complain if a class derives from a base class which has a public non virtual destructor (or no destructor) defined. And not just warn about it.

4
Sutter wrote on that in Virtuality.Georg Fritzsche
that was one awesome read! thanksneal aise

4 Answers

12
votes

The problem with your idea is that it's conceivable that someone is using a non-virtual base class destructor as an optimization (if you're never going to destroy via a base-class pointer, then the missing virtual won't hurt you, and still avoids the vtable entry).

Since it COULD be used, it's allowed. I'd think an optional compiler warning might be a good idea, but not something in the language spec.

8
votes

Because it's perfectly valid to have a non-virtual destructor. If sub classes are only designed to be stack allocated, for example, there's no need for a virtual destructor. Why require clients to have all the vtbl machinery when a class is only supposed to be a decorator?

It also makes little sense to have a virtual destructor when a class is meant to be inherited from privately (implemented-in-terms-of).

This all said, a destructor should usually be public and virtual or protected, unless a class is not meant to be a base class.

5
votes

Virtual destructor is only needed if you perform polymorphic destruction of the object through delete. That, in turn, immediately implies dynamically allocated (new-ed) objects.

If you don't allocate objects dynamically, you don't need the virtual destructor. This immediately offers an unlimited source of use-cases when the virtual destructor in base class is not necessary.

If you allocate objects dynamically, but never destroy them polymorphically, you don't need the virtual destructor. This adds another set of use-cases when the virtual destrcutor in base class is not necessary.

2
votes

There are different issues with what you propose, the first of which is already dealt in other answers: you only need virtual destructors if you intend to delete through a pointer to a base (a general recommendation is to provide either a public virtual destructor or a protected non-virtual destructor as that would inhibit deletion through the base class).

There is another issue in that when a compiler sees a class definition it cannot possibly know whether it is going to be derived or not. Consider if you implement a base class in a translation unit. At a later time you derive from the class. If that derivation would imply making the constructor virtual the base class translation would have to be recompiled, or else the ODR (One Definition Rule) would be broken in your program.

If you add other translation units to the mix, things get even worse. Whenever you include a header file from a translation unit you would be forced to also manually include at least one header where a derived object from that class is defined (increasing coupling), or else, again, the compiler would generate a different definition for that single class in that translation unit (compared to the translation unit where the derived class is defined) breaking the ODR again.

The problem is that the compiler only has a partial view of your project, and cannot really infer what you need/want from what it sees.