![](/img/trans.png)
[英]Call a derived class' (non-virtual) function in the base class' Destructor
[英]Why is base-class destructor called on derived object when destructor of derived class is non-virtual?
为什么在下面的例子中调用所有析构函数, ~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;
}
一旦A
的析构函数被声明为virtual
,所有派生类的析构函数也是virtual
,即使它们没有明确声明为这样。所以你看到的行为正是预期的
派生对象中的销毁顺序与构造的顺序完全相反:首先调用派生类最多的析构函数,然后调用基类的析构函数。
析构函数可以定义为虚拟或甚至纯虚拟。 如果您希望通过指向基类的指针销毁派生类,则可以使用虚拟析构函数。 这将确保调用大多数派生类的析构函数:
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
如果A没有虚拟析构函数,则通过类型A的指针删除b1只会调用A的析构函数。 在这种情况下,为了强制调用B的析构函数,我们必须将A的析构函数指定为虚拟:
virtual ~A();
正如@juanchopanza所说 - 声明基础析构函数虚拟意味着所有后代都有虚拟析构函数。 这种继承的虚拟性对于任何方法都是相同的 ,而不仅仅是析构函数。
这就是为什么我采访了那些不知道关键字做了什么的人,因为他们只需要覆盖从框架派生的方法,所以他们都是虚拟的(感叹)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.