Destructors And Inheritance

Plain (Base) Class

  • Destructors are almost ordinary methods

  • Except: they cannot be overridden

  • This just would not make sense ⟶ resource leaks in base class

  • But wait … lets start with a plain base class

#include <iostream>


class Base
{
public:
    ~Base() 
    {
        std::cout << "Base::~Base()" << std::endl;
    }
};

int main()
{
    Base b;

    return 0;
}
$ ./inher-oo-dtor-base
Base::~Base()

Derived Class, And Destructor

  • Destroying derived class calls all destructors up to the innermost base class

#include <iostream>


class Base
{
public:
    ~Base() 
    {
        std::cout << "Base::~Base()" << std::endl;
    }
};

class Derived : public Base
{
public:
    ~Derived()
    {
        std::cout << "Derived::~Derived()" << std::endl;
    }
};

int main()
{
    Derived d;

    return 0;
}
$ ./inher-oo-dtor-derived-novirtual
Derived::~Derived()
Base::~Base()

And Base Class Conversion?

  • C++ mantra: unless you know a lot you cannot write bug-free code

  • Problem: just like base class conversion with ordinary (non-virtual) methods

  • Which destructor is called when Derived is destroyed through a Base*?

  • Spoiler: only Base::~Base()

  • (Obviously only apparent when objects are allocated from dynamic memory)

#include <iostream>


class Base
{
public:
    ~Base() 
    {
        std::cout << "Base::~Base()" << std::endl;
    }
};

class Derived : public Base
{
public:
    ~Derived()
    {
        std::cout << "Derived::~Derived()" << std::endl;
    }
};

int main()
{
    Base* b = new Derived;      // <--- Base* points to Derived object
    delete b;                   // <--- BUG: Derived's destructor not called

    return 0;
}
$ ./inher-oo-dtor-derived-novirtual-base-conversion
Base::~Base()