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

C++ 当派生类的析构函数是非虚拟的时,为什么对派生对象调用基类析构函数?,c++,polymorphism,virtual-destructor,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

为什么在下面的示例中调用所有析构函数,
~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;
}
#包括
使用名称空间std;
甲级
{
公众:
虚拟~A()
{

cout一旦
A
的析构函数声明为
virtual
,所有派生类的析构函数也都是
virtual
,即使它们没有显式声明为virtual
。因此,您看到的行为正是预期的

派生对象中的销毁顺序正好相反 构造顺序:首先是最派生的析构函数 调用类,然后调用基类的析构函数

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

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


正如@juanchopanza所说,声明基本析构函数为虚拟意味着所有子体都有虚拟析构函数。这种继承的虚拟性对于任何方法都是一样的,不仅仅是析构函数


这就是为什么我采访了一些人,他们不知道关键字做了什么,因为他们只需要重写从框架派生的方法,所以他们都是虚拟的(叹气).

因为这就是语言规则所说的应该发生的。@spin_八a
D
是通过一个指向
a
的指针来访问的,这就是delete被调用的地方。如果
a
的析构函数不是虚拟的,那么只会调用
~a()
。你可以轻松地检查自己。“甚至是纯虚拟的”-为了防止运行时错误,您必须为纯虚拟析构函数创建body,以便在虚拟表中为该析构函数分配地址,而不仅仅是nullptr
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
virtual ~A();