I've written this test code that uses three types: struct One
is a normal type with no virtual members, struct Two : One
has a pure virtual function and a virtual destructor, and struct Three : Two
implements Two
's interface.
#include <iostream>
struct One
{
~One() {
std::cout << "~One()\n";
}
};
struct Two : One
{
virtual ~Two() {
std::cout << "~Two()\n";
}
virtual void test() = 0;
};
struct Three : Two
{
virtual ~Three() {
std::cout << "~Three()\n";
}
virtual void test() {
std::cout << "Three::test()\n";
}
};
int main()
{
Two* two = new Three;
two->test();
One* one = two;
delete one;
}
Unsurprisingly, the output was this:
Three::test()
~One()
Is there any way to fix this other than making every destructor virtual? Or should programmers just be careful not to run into this situation? I find it odd that there's no warning when compiling this.
The only "fix" is not to delete the objects through a pointer to
One
.If this is a frequent problem, or not, depends on how your classes are used. For example, the standard library contains structs like
unary_function
without a virtual destructor, but we hardly ever see it misused like this.