Consider a simple interface/implementation design:
class Base
{
public:
virtual ~Base()
{
// Virtual empty destructor
}
};
class Derived : public Base
{
public:
virtual ~Derived()
{
// Lots of clean up code here
// ...
}
};
With this design, I understand that the following code is safe and valid:
Base* base = new Derived();
delete base; // Both Base::~Base and Derived::~Derived get called
However, imagine if there was a new class:
class DerivedEx : public Derived
{
public:
// No destructor here, relying on default destructor generated by compiler
};
Is DerivedEx "safe"?
For safety, I always assumed that I'd have to implement a virtual empty destructor in DerivedEx. But I'm wondering if this is redundant and unnecessary and whether or not there are any 'gotchas' that I'm not aware of.