When should your destructor be virtual? [duplicate]
Possible Duplicate:
When to use virtual destructors?
When should your C++ object's destructor be virtual
?
Solution 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.