Java and C# support the notion of classes that can't be used as base classes with the final
and sealed
keywords. In C++ however there is no good way to prevent a class from being derived from which leaves the class's author with a dilemma, should every class have a virtual destructor or not?
Edit: Since C++11 this is no longer true, you can specify that a class is final
.
On the one hand giving an object a virtual destructor means it will have a vtable
and therefore consume 4 (or 8 on 64 bit machines) additional bytes per-object for the vptr
.
On the other hand if someone later derives from this class and deletes a derived class via a pointer to the base class the program will be ill-defined (due to the absence of a virtual destructor), and frankly optimizing for a pointer per object is ridiculous.
On the gripping hand having a virtual destructor (arguably) advertises that this type is meant to be used polymorphically.
Some people think you need an explicit reason to not use a virtual destructor (as is the subtext of this question) and others say that you should use them only when you have reason to believe that your class is to be derived from, what do you think?
The question is really, do you want to enforce rules about how your classes should be used? Why? If a class doesn't have a virtual destructor, anyone using the class knows that it is not intended to be derived from, and what limitations apply if you try it anyway. Isn't that good enough?
Or do you need the compiler to throw a hard error if anyone dares to do something you hadn't anticipated?
Give the class a virtual destructor if you intend for people to derive from it. Otherwise don't, and assume that anyone using your code is intelligent enough to use your code correctly.
Every abstract class should either have a,
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 a class not intended to delete through a pointer to it, there is no reason whatsoever to have a virtual destructor. It would not only waste resources, but more importantly it would give users a wrong hint. Just think about what crappy sense it would make to give
std::iterator
a virtual destructor.Check this article from Herb Sutter:
Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual.
I'll add that there have been times when I have scratched my head for a while on destructors not getting called when I forgot a virtual in the parent or child class. I guess I know to look for that now though. :)
Someone might argue that there are times the parent class does something in its destructor that a child should not do... but that's probably an indicator of something wrong with your inheritance structure anyway.
Base class becomes abstract class, when it contains at least one pure virtual function. If Base does not have a virtual destructor and Derived (derived from Base) does, then you can safely destroy a Derived object through a Derived object pointer but not through a Base object pointer.