3

I am basically plagiarizing When NOT to use virtual destructors?. The excellent answers remind us that C++ is pay only for what you use.

However, the Standard is a couple of thousand pages long. The d-tor of a class containg at least one virtual method is implicitly virtual. wouldn't have loaded it too much.

Why do we need to keep the cognitive burden of doing it, to teach newbies to do it, to sometimes forget and thus create horrible bugs?

I hope the question has an objective answer - the language spec has been deliberated for some time now.

Christophe
  • 74,672
  • 10
  • 115
  • 187
Vorac
  • 7,073
  • 7
  • 38
  • 58
  • [Is asking “why” on language specifications still considered as “primarily opinion-based” if it can have official answers?](https://meta.stackoverflow.com/a/323382/839601) – gnat Jul 15 '20 at 18:03
  • 1
    Something being absent from the standard doesn't necessarily mean it was purposefully kept out of the standard. It can also mean no-one tried to get it in there/made the effort to explore all the potential ramifications. – Mat Jul 15 '20 at 18:09
  • Related: https://stackoverflow.com/questions/28909598/eliminating-instantiation-of-useless-destructor-calls – πάντα ῥεῖ Jul 15 '20 at 20:57
  • 2
    The number of cases where a virtual destructor is not needed despite of the presence of another virtual function is very small, indeed, so I suppose a `nonvirtual` destructor keyword for those corner cases might make more sense. However, it would be inconsistent with the rest of the language and be a breaking change if applied to existing codebases. On top of that, virtual functions are not as important today as they were when C++ was invented. Modern C++ is all about generic programming, not OOP. No wonder that nobody ever invested time, energy and money into an ISO proposal for this idea. – Christian Hackl Jul 16 '20 at 03:21

1 Answers1

6

As you rightly point out, C++ obeys the language design principle of "pay only for what you use".

Making the destructor virtual when there is at least one virtual method is a rule of thumb, and nothing more:

  • There are plenty of cases where you can have a class with a virtual function without needing a virtual destructor.
  • Conversely, there are as many cases where you need a virtual destructor even when you don't have any other virtual function.

Bjarne Stroustrup explained the need for virtual destructors in his book The Design and evolution of C++ (page 216):

The use of a virtual destructor is crucial for getting destruction right in cases in which a user deletes an object of a derived class through a pointer of the base class.

Why? Because in this exact scenario, without virtual destructor, it would be the destructor of the base class that would be called, and this could miss a lot of resources to be freed in the derived class.

So the real need for virtual destructor is not at all the existance of a virtual function. This known rule of thumb/guideline is there, only because: when you have at least one virtual function, it is very probably because you want polymorphism and access objects of derived classes through pointers of the base class. And if you do this, there's also a higher probability that you delete some of these objects via their base pointers.

If the language specifications should provide for a rule to automatically define when a destructor has to be virtual, it would certainly not be the simple sentence that you propose, but dozen of pages to cover all the tricky special cases. And since nobody would be sure that it's fully accurate.... Wait! Isn't that what happened? ;-)

Christophe
  • 74,672
  • 10
  • 115
  • 187
  • 1
    Still seems fishy. Isn't it better to default the virtual class destructors to `virtual`, and have something like a `nonvritual` keyword. That way the consequences of a mistake are to make your code infinitesimally smaller, rather than mega broken. – Alexander Jul 16 '20 at 17:08
  • 2
    @Alexander-ReinstateMonica Well, classes without virtual functions *should not* default to a virtual dtor. That would just be uncomfortable and nearly always overridden. Next, what about those only inheriting virtual functions? Also, does it depend on whether the base-dtor was virtual? Finally, introducing a whole new keyword just for making the dtor non-virtual? What a drag. At the very least, we could repurpose `final` for that, as it has no real use for the dtor yet. – Deduplicator Jul 16 '20 at 18:26