在派生类中覆盖哪个基类的虚拟析构函数

时间:2018-01-26 23:35:27

标签: c++ class inheritance virtual destructor

当派生类没有立即派生,而是派生自已派生的类时,我对覆盖函数感到困惑。

#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;
}

在两种情况下都会调用MostDerived的析构函数。我想知道它是否只需要最基类的析构函数被声明为虚拟,并且在这种情况下,从它继承的所有其他类都具有虚拟析构函数,如果你得到的话,它会覆盖所有其他析构函数。我的意思。

我不确定我是否有意义,基本上如果我有一系列10个类,每个类继承自最后一个,链中的任何析构函数都会覆盖所有比它更基础的析构函数?

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

Grandson的析构函数将覆盖它上面的所有类,但不是GreatGrandson的析构函数?

而且,一旦基类的析构函数或其他函数被声明为虚拟,它的后代都不需要再次声明为虚拟?

2 个答案:

答案 0 :(得分:3)

  

链中的任何析构函数都会覆盖所有比它更基础的析构函数?

是的,差不多。如果您不编写析构函数,则执行将隐式提供析构函数。所以它也会隐含地覆盖基类d&#39; tor。

  

Grandson的析构函数将覆盖它上面的所有类,但不是GreatGrandson的析构函数?

它会覆盖Son的d。哪个扩展名会覆盖Father&#39; s等等。是的并且它无法覆盖GreatGrandson,因为在其定义时,它无法展望未来并且知道GreatGrandson将会存在。

  

而且,一旦基类的析构函数或其他函数被声明为虚拟,它的后代都不需要再次声明为虚拟?

是的,与任何虚拟功能相同。一旦声明为虚拟,它在任何派生类中都是虚拟的。

答案 1 :(得分:2)

析构函数会覆盖基类的所有虚拟析构函数,包括间接碱基。此外,覆盖虚拟功能的功能本身也是虚拟的。因此,是的,隐式定义的Derived析构函数是虚拟的,~Base~Derived都被~MostDerived覆盖。当使用指向基类的指针来销毁派生类类型的对象时,需要为虚拟的析构函数是基类的析构函数。 (派生类中的那个将是隐式虚拟的。)