Search code examples
c++classinheritancevirtualdestructor

Which base class's virtual destructor is overriden in a derived class


I'm confused about overriding functions when the derived class isn't immediately derived, but derived from an already derived class.

#include <iostream>

struct Base
{ 
    virtual ~Base() { std::cout << "Base destructor called\n"; }
};

struct Derived : Base
{
    Derived() {}
    // Implicitly supplied destructor, I'm guessing. Which is also virtual?
};

struct MostDerived : Derived
{
    MostDerived(){};
    ~MostDerived() { std::cout << "MostDerived destructor called\n"; }
};

int main()
{
    Derived* d = new MostDerived();
    delete d;
    Base* b = new MostDerived();
    delete b;
}

In both cases MostDerived's destructor is called. I'm wondering if it's only required that the most base class has a destructor declared virtual, and in that case all other classes inheriting from it all have virtual destructors that override every other destructor further upstream, if you get my meaning.

I'm not sure if I made sense, basically if I had a series of 10 classes with each one inheriting from the last one, any destructor in the chain will override all the destructors that are more base than it?

struct GreatGrandfather{~virtual GreatGrandfather(){}}; // Only this is necessary
struct Grandfather : GreatGrandfather {};
struct Father : Grandfather{};
struct Son : Father{};
struct Grandson : Son {};
struct GreatGrandson : Grandson{};

Grandson's destructor will override all of the classes above it, but not GreatGrandson's destructor?

And also, once a base class's destructor or other function is declared virtual none of its descendants need to be declared virtual again?


Solution

  • any destructor in the chain will override all the destructors that are more base than it?

    Yes, pretty much. A destructor will be implicitly supplied by the implementation if you don't write one. So it will also implicitly override the base class d'tor.

    Grandson's destructor will override all of the classes above it, but not GreatGrandson's destructor?

    It will override Son's d'tor. Which by extension overrides Father's and so forth. So yes. And it can't override GreatGrandson, since at the point of its definition it cannot look into the future and know GreatGrandson will exist.

    And also, once a base class's destructor or other function is declared virtual none of its descendants need to be declared virtual again?

    Yes, same as with any virtual function. Once declared virtual, it's always virtual in any derived class.