Original link: Omit a virtual destructor / LinkedIn.
He is correct. The C++ standard says:
In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.so it is UB.
It is quite common for compiler to just not call the child class destructor.
To test your C++ compiler:
#include
using namespace std;
class P1
{
protected:
const char *lbl;
public:
P1(const char *lbl)
{
this->lbl = lbl;
cout << " class P1 instance " << lbl << " allocating" << endl;
}
~P1()
{
cout << " class P1 instance " << lbl << " deallocating" << endl;
}
};
class C1 : public P1
{
public:
C1(const char *lbl) : P1(lbl)
{
cout << " class C1 instance " << lbl << " allocating" << endl;
}
~C1()
{
cout << " class C1 instance " << lbl << " deallocating" << endl;
}
};
class P2
{
protected:
const char *lbl;
public:
P2(const char *lbl)
{
this->lbl = lbl;
cout << " class P2 instance " << lbl << " allocating" << endl;
}
virtual ~P2()
{
cout << " class P2 instance " << lbl << " deallocating" << endl;
}
};
class C2 : public P2
{
public:
C2(const char *lbl) : P2(lbl)
{
cout << " class C2 instance " << lbl << " allocating" << endl;
}
virtual ~C2()
{
cout << " class C2 instance " << lbl << " deallocating" << endl;
}
};
int main()
{
cout << "C1 = new C1:" << endl;
C1 *a = new C1("a");
delete a;
cout << "P1 = new C1:" << endl;
P1 *b = new C1("b");
delete b;
cout << "C2 = new C2:" << endl;
C2 *c = new C2("c");
delete c;
cout << "P2 = new C2:" << endl;
P2 *d = new C2("d");
delete d;
return 0;
}