Pure virtual destructors in C++
November 13th, 2010 at 6:34 pmTo work correctly, classes with virtual methods must also have virtual destructors. Interestingly, virtual destructors can be declared pure, which can be useful in some cases.
Imagine you have a base class you want to make abstract. In this base class all methods have meaningful default implementations, and you want to allow the derived classes to inherit them as-is. However, to make a class abstract, at least one of its methods must be made pure virtual, which means the derived classes must override it. How do you make the class abstract in this case?
The answer is: declare the destructor pure virtual. This will make your class abstract without forcing you to declare any other method pure virtual.
// Abstract base class - can't be instantiated
//
class Base
{
public:
virtual ~Base() = 0;
virtual void method();
};
Base::~Base()
{
// Compulsory virtual destructor definition,
// even if it's empty
}
void Base::method()
{
// Default implementation.
// Derived classes can just inherit it, if needed
}
// We can now derive from Base, inheriting the
// implementation of method()
//
class Derived : public Base
{
public:
~Derived()
{}
};
While defining (providing an implementation) pure virtual methods is rarely useful, you must define a pure virtual destructor. This is because the destructor of a base class is always called when a derived object is destroyed. Failing to define it will cause a link error.
Related posts:

November 15th, 2010 at 01:19
I believe failing to define the destructor will cause a link error, not a compile error.
Very well written, though. This is one of those ugly corners of C++ that the programmer shouldn’t have to know about, but does.
November 15th, 2010 at 06:18
@Paul,
Thanks! I wrote “compilation error” as a generic term for “error during the compilation process”, but thinking about this again, just going with “link error” is clearer, so I fixed the post.
November 15th, 2010 at 13:37
When you use a abstract class and want to inherit the API, you have to use public inheritence.
November 15th, 2010 at 22:05
I have learned to just do this all the time for abstract base classes (ABC).
To me, at least for my own C++, “interface” has become synonymous with “has a pure virtual destructor”. This way I never forget to (a) declare a virtual destructor, or (b) have at least one pure method.
Important: if you want to write your ABC entirely in a header file, you need to declare your destructor definition with “inline” so as to not have multiple re-definitions.
November 16th, 2010 at 07:01
@Mickaël
Thanks – it was a typo, added the
publicinheritance specifier@Michal:
Interesting, thanks. Indeed, there’s no harm defining it pure always in a ABC.
November 16th, 2010 at 18:32
I don’t think “must” is the correct word here. You have an option to not to define a Virtual desctructor. Doing would just create a bunch of leak when derived classes allocate resources which won’t get garbage collected properly.
November 17th, 2010 at 02:27
There are actually two things you can do to allow correct use of destructors in virtual classes. You can either declare them as public virtual or protected non-virtual. They correspond to the cases where:
1) You can delete the memory through the base-class pointer
2) You can’t delete the memory through the base-class pointer
For case 2 (a protected non-virtual destructor) you are making a statement about memory ownership that basically says ‘if you have a pointer to this base class, you don’t own the memory and therefore trying to delete it here is an error’.
Incidentally, the exact error (resource leaks) only occurs in a situation like the following:
)
class A {};class B : A {};
...
A *ptr = new B();
delete ptr;
(all methods removed to make the code as succinct as possible). Basically the resource leak only occurs when you delete the derived class through a pointer to the base class (which is why a protected non-virtual destructor is fine, assuming you don’t do something insanely stupid like ‘delete this;’
November 17th, 2010 at 07:40
@David,
I think the code sample you present (which is case 1 according to your earlier enumeration) is quite common, which is why having a virtual destructor in
Ais needed. Without a virtual destructor, only theApart ofBwill be cleaned up, which is a memory leak.November 17th, 2010 at 09:15
@ellben
Or you make the destructor protected non-virtual, which makes the ‘delete ptr;’ statement something that won’t compile
November 17th, 2010 at 09:49
Oh, also I just realised that it isn’t an automatic memory leak just from not making the destructor virtual. As an example:
class A {public:
A() {
c = new C();
]
~A() {
delete c;
]
};
class C {};
class B : A{
};
...
A* ptr = new B();
delete ptr;
The above won’t cause a resource leak as all of the memory allocated in the ‘new’ statement is freed, but the destructor in B isn’t called, which is fine in this circumstance. However, if B looked like:
class B : A {public:
C* c_;
B() {
c_ = new C();
}
~B() {
delete c_;
}
];
Now we have a resource leak.
In the situation where A is a normal subclass, you’d make the destructor virtual, as
deleteing a derived class through a subclass makes sense. When A is more like an interface though and contains just pure virtual methods (potentially with several interfaces being inherited by one class) then making the interface destructor protected non-virtual makes more sense as you generally don’t want to allow someone todeletea pointer to an interface.November 17th, 2010 at 10:56
@David,
I agree that when no extra resources are allocated in the derived objects, no leak will occur. However, as a good design practice, I would always use a virtual base destructor in a class with virtual functions that’s to serve as a base of a hierarchy.
November 18th, 2010 at 07:02
There are even more complex situations where a Base can be without a virtual destructor, be used polymorphically, and yet still call the Derived destructor properly: read the most important const, guru question #3
Just FYI, I tested this with a protected base destructor, and it still compiles, so, I can think of no example where I wouldn’t apply the two rules David outlined. Thanks for pointing that part out.
November 18th, 2010 at 07:26
@Michal,
Thanks for the link – I learned something new. Still, if I can, I will avoid code where I have to read a GoTW entry to just know it works. Having a virtual base destructor is more straightforward. Are there any important use-cases where you’d like to avoid it?
November 18th, 2010 at 18:48
Pretty close to this: http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/
November 18th, 2010 at 20:08
@rmn,
It is quite close, indeed. Had I seen your post, I wouldn’t have written this one for sure. As in most blog posts, I don’t claim originality. I assume this issue of pure virtual destructors is covered in at least another dozen posts/articles/discussions online.
November 18th, 2010 at 23:39
For complete clarity, I think it’s also worth mentioning that the subject of virtual destructors is also covered in either ‘Effective C++’ or ‘More Effective C++’ too, which I’d consider must-reads for C++ devs (although make sure you grab the 2nd edition of Effective C++, as the first edition is now quite old and not as applicable)
January 24th, 2011 at 19:54
It is also worth noting that there is nothing wrong with a pure virtual function having an implementation.