3

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.

swaplink
  • 43
  • 2
  • 8
Zeenobit
  • 4,954
  • 3
  • 34
  • 46

3 Answers3

8

Yes, it's still safe.

A destructor is automatically virtual if any base class destructor is virtual. This is true whether you type ~Foo(); or virtual ~Foo(); or neither and just allow the compiler to generate the implicitly defined destructor.

aschepler
  • 70,891
  • 9
  • 107
  • 161
  • So you mean the `virtual` for `Derived::~Derived` would be redundant as well? – Zeenobit Jan 11 '13 at 15:24
  • 1
    @Farbod T. It's redundant only to the compiler. To your future human maintainers it's a lifesaver to understand what the program is doing. – Mark B Jan 11 '13 at 15:28
4

It is safe. You just need to ensure that the destructor in the base class is virtual.
As long as your Base class destructor is virtual the compiler will take care of calling all the destructors in the correct order.

Whether you need a destructor in most derived class depends on that class itself & that decision is usually made based on Rule of Three.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
3

Yes, it is safe.

The implicitly generated destructor will be virtual, since there is a base class with a virtual destructor, and will correctly call the destructors of all non-trivial members and base classes.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644