Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should every class have a virtual destructor?

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?

like image 478
Motti Avatar asked Dec 09 '08 18:12

Motti


People also ask

Do I always need a virtual destructor?

Virtual keyword for destructor is necessary when you want different destructors should follow proper order while objects is being deleted through base class pointer.

Does every class need a destructor?

Containers may need to delete all of their elements. In summary, if the class acquires resources or requires specialized cleanup (let's say in a determined order), there should be destructor.

When should you use a virtual destructor?

Virtual destructors in C++ are used to avoid memory leaks especially when your class contains unmanaged code, i.e., contains pointers or object handles to files, databases or other external objects. A destructor can be virtual.

Can a class have virtual destructor yes or no?

Yes, it is possible to have a pure virtual destructor. Pure virtual destructors are legal in standard C++ and one of the most important things to remember is that if a class contains a pure virtual destructor, it must provide a function body for the pure virtual destructor.


2 Answers

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.

like image 125
Johannes Schaub - litb Avatar answered Oct 13 '22 23:10

Johannes Schaub - litb


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.

like image 37
jalf Avatar answered Oct 13 '22 21:10

jalf