When should your destructor be virtual?

18,476

Solution 1

  1. You need virtual destructor when at least one of class methods is virtual.

This is because the reason for virtual method is that you want to use polymorphism. Meaning you will call a method on the base class pointer and you want the most derived implementation - this is the whole point of polymorphism.

Now if you did not have virtual destructor and through the pointer to base class you call destructor you end up calling base class destructor. In this case you want polymorphism to work on your destructor as well, e.g. through calling destructor on your base class you want to end up calling destructor of your most derived class not your base class.

class A
{
   virtual void f() {}
   ~A() {}
}

class B : public A
{
   void f() {}
   ~B() {}
}

A * thing = new B();
thing->f(); // calls B's f()
delete thing; // calls ~A(), not what you wanted, you wanted ~B()

having ~A() virtual turns on polymorphism

virtual ~A() {}

So when you now call

delete thing;

~B() will be called.

You would declare virtual destructors when you design class as an interface e.g. you expect it to be extended or implemented. A good practice in that case is to have a interface class (in the sense of Java interfaces) with virtual methods and virtual destructor and then have concrete implementation classes.

You can see that STL classes don't have virtual destructors so they are not supposed to be extended (e.g. std::vector, std::string ...). If you extend std::vector and you call destructor on base class via pointer or reference you will definitely not call your specialized class destructor which may lead to memory leaks.

Solution 2

From Stroustrup's C++ Style and Technique FAQ:

So when should I declare a destructor virtual? Whenever the class has at least one virtual function. Having virtual functions indicate that a class is meant to act as an interface to derived classes, and when it is, an object of a derived class may be destroyed through a pointer to the base.

Lots of additional info on when your destructor should be virtual on the C++ FAQ. (thanks Stobor)

What is a virtual member? From the C++ FAQ:

[20.1] What is a "virtual member function"?

From an OO perspective, it is the single most important feature of C++: [6.9], [6.10].

A virtual function allows derived classes to replace the implementation provided by the base class. The compiler makes sure the replacement is always called whenever the object in question is actually of the derived class, even if the object is accessed by a base pointer rather than a derived pointer. This allows algorithms in the base class to be replaced in the derived class, even if users don't know about the derived class.

The derived class can either fully replace ("override") the base class member function, or the derived class can partially replace ("augment") the base class member function. The latter is accomplished by having the derived class member function call the base class member function, if desired.

Solution 3

I've recently come to conclude that the fully correct answer is this:

Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual.

And of course Herb Sutter gives the rationale to his claim. Note that he does go beyond the usual answers "when someone will delete a derived-class object via a base-class pointer" and "make your destructor virtual if your class has any virtual functions".

Solution 4

If you will (or even might) destroy objects of a derived class through a base class pointer, you need a virtual destructor.

I take the approach that if I'm going to derive from a class AT ALL, then it shall have a virtual destructor. There are effectively no cases in the code I write where the performance implications of a virtual destructor matter, and even if it's not actually needed today, it might end up needing it in the future when the class is modified.

Basically: Put virtual on all base class destructors unless you have a good, well-thought out reason not to.

That's just another rule of thumb, but it's one that keeps you from making later mistakes.

Share:
18,476

Related videos on Youtube

Michael Zhou
Author by

Michael Zhou

Love Games!

Updated on July 02, 2020

Comments

  • Michael Zhou
    Michael Zhou almost 4 years

    Possible Duplicate:
    When to use virtual destructors?

    When should your C++ object's destructor be virtual?

  • Nubzor
    Nubzor almost 15 years
    +1 nice copy paste quote from Mr S., can't really beat that answer
  • Stobor
    Stobor almost 15 years
  • Tom Leys
    Tom Leys almost 15 years
    In that case, Stobor, there was little point instantiating the derived class. There is no way to access the derived class's methods without a dynamic_cast, which implies knowledge of the object type. That knowledge could be used to dynamic_cast before the destructor too. Of course, the virtual method thing is just a rule of thumb. Not surprising your contrived example shoots a hole in it
  • hookenz
    hookenz almost 15 years
    This is not quite correct e.g. If a base class A (non virtual destructor defined) doesn't have resources, and class B (a subclass of A) does have resources and we have something like B *b = new B(); A *a = static_cast<A>(b); delete a; then the result is actually undefined in the standard. It might free the resources, or it might not. More often than not memory is leaked. So the correct answer would be - if you've got sub-classes, then the base class needs to have a virtual destructor to ensure resources are correctly freed.
  • Tom
    Tom almost 15 years
    C++ didn't give you that flexibility just so you could throw it away. Put another way, "Unless I'm really concerned with the storage and performance overhead of a vtable, I'm going to use an easier language like Python or Lua."
  • Steve Jessop
    Steve Jessop almost 15 years
    In the astonishingly rare situation where Stroustrup's deduction doesn't hold (i.e. the class is intended to act as an interface to derived classes, but the desired interface is that an object of a derived class MAY NOT be destroyed through a pointer to the base) then IIRC you can have a protected non-virtual destructor. It's next to pointless making it non-virtual AFAIK, since virtual destructors are hardly a common performance bottleneck. But stopping clients from deleting stuff themselves might be a useful restriction, and it could then be non-virtual if desired.
  • gbjbaanb
    gbjbaanb almost 15 years
    @Tom: yes, you can just throw the flexibility away. C++ gives you the flexibility so you can remove it when you want, or add it when you want. Lesser languages enforce it all the time. So for C++, you might as well put virtual dtors everywhere, except in those cases where you've thought about it and decided you don't want them.
  • Nubzor
    Nubzor almost 15 years
    I would not narrow it down to those 2 options. You use tools to build what is required, in this case features of programming language. If you create every public destructor public you turn on polymorphism for each of those classes, probably in 90% of those cases you don't need that and you end up with unnecessary overhead.
  • sebkraemer
    sebkraemer over 4 years
    The exact answer I was looking for after choosing the wrong answer in the pluralsight skill IQ question, thanks
  • Marine Galantin
    Marine Galantin over 3 years
    it has been included in the guidelines : C.35 : github.com/isocpp/CppCoreGuidelines/blob/master/…