当派生类的析构函数是非虚拟的时,为什么基类析构函数在派生对象上调用?

Emp*_*ata 6 c++ polymorphism virtual-destructor

为什么所有析构函数,~D(),~C(),~B(),~A()被称为在下面的例子吗?

只有一个虚拟析构函数:A.

这是代码:

#include<iostream>
using namespace std;

class A
{
public:
  virtual ~A()
  {
    cout<<"destruct A\n";
  }

};
class B:public A
{
public:
  ~B()
  {
  cout<<"destruct B\n"; 
  }
};
class C:public B
{
public:
  ~C()
  {
    cout<<"destruct C\n";
  }
};
class D:public C
{
public:
   ~D()
   {
     cout<<"destruct D\n"; 
   }
};

int main()
{
    A* ptr = new D();
    delete ptr;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

jua*_*nza 7

一旦A声明virtual了析构函数,所有派生类的析构函数也是virtual,即使它们没有明确声明为这样.所以你看到的行为正是预期的


Ani*_*dha 7

派生对象中的销毁顺序与构造的顺序完全相反:首先调用派生类最多的析构函数,然后调用基类的析构函数.

析构函数可以定义为虚拟或甚至纯虚拟.如果您希望通过指向基类的指针销毁派生类,则可以使用虚拟析构函数.这将确保调用大多数派生类的析构函数:

A* b1 = new B;//if A has a virtual destructor
delete b1;//invokes B's destructor and then A's

A* b1 = new B;//if A has no virtual destructor
    delete b1;//invokes A's destructor ONLY
Run Code Online (Sandbox Code Playgroud)

如果A没有虚拟析构函数,则通过类型A的指针删除b1只会调用A的析构函数.在这种情况下,为了强制调用B的析构函数,我们必须将A的析构函数指定为虚拟:

virtual ~A();
Run Code Online (Sandbox Code Playgroud)

参考