析构器¶
当对象超出作用域时,自动调用析构器进行删除
声明¶
- 不接受参数
- 不返回值
- 无法声明为
const,volatile
或static
- 可以声明为
virtual
。使用虚拟析构函数,可以在不知道对象类型的情况下销毁对象 - 使用虚拟函数机制调用对象的正确析构函数。注意,析构函数也可以声明为抽象类的纯虚拟函数
使用¶
当以下事件发生时调用析构器:
- 具有块作用域的本地(自动)对象超出作用域
- 使用
new
运算符分配的对象使用delete
显式释放 - 临时对象的生存期结束
- 程序结束后为全局或静态对象调用析构器
- 使用析构函数的完全限定名显式调用
使用限制如下:
- 无法获取析构器地址
- 派生类无法继承基类的析构器
调用顺序¶
- 首先调用对象类的析构器,执行函数体
nonstatic
成员对象的析构器以声明的相反顺序调用- 以声明的相反顺序调用非虚拟基类的析构器
- 以声明的相反顺序调用虚拟基类的析构器
虚拟基类¶
虚拟基类的析构函数的调用顺序与它们在有向无环图中的出现顺序相反(深度优先、从左到右、后序遍历)。下图描述了继承关系图
class A
class B
class C : virtual public A, virtual public B
class D : virtual public A, virtual public B
class E : public C, public D, virtual public B
首先C/D
是非虚拟基类调用,非虚拟基类的析构函数的调用顺序与基类名称的声明顺序相反;然后才是虚拟基类的析构器调用。销毁顺序为E->D->C->B->A
显式析构调用¶
s.String::~String(); // non-virtual call
ps->String::~String(); // non-virtual call
s.~String(); // Virtual call
ps->~String(); // Virtual call
对未定义析构函数的显式调用没有任何效果