6.2 用析构函数确保清除
作为一个C程序员,可能经常想到初始化的重要性,但很少想到清除的重要性。毕竟,清除一个int时需要做什么?仅仅是忘记它。然而,在一个库中,对于一个曾经用过的对象,仅仅“忘记它”是不安全的。如果它修改了某些硬件参数,或在屏幕上显示了一些字符,或在堆中分配了一些内存,那么将会发生什么呢?如果只是“忘记它”,对象就永远不会消失。在C++中,清除就像初始化一样重要。它通过析构函数来保证清除的执行。
析构函数的语法与构造函数一样,用类的名字作为函数名。然而析构函数前面加上一个代字号(~),以和构造函数区别。另外,析构函数不带任何参数,因为析构不需任何选项。下面是一个析构函数的声明:
当对象超出它的作用域时,编译器将自动调用析构函数。可以看到,在对象的定义点处构造函数被调用,但析构函数调用的惟一证据是包含该对象的右括号。即使用goto语句跳出这一程序块(为了与C语言向后兼容,goto在C++中仍然存在,当然有时也是为了方便),析构函数仍然被调用。应该注意非局域的goto语句(nonlocal goto),它们是用标准C语言库中的setjmp()和longjmp()函数实现的,这些非局域的goto语句将不会引发析构函数的调用(这是一种规范:但有的编译器可能并不用这种方法来实现。对那些不在规范中的特征的依赖性意味着这样的代码是不可移植的)。
下例说明了构造函数与析构函数的上述特征:
下面是上面程序的输出结果:
可以看到析构函数在包括它的右括号处被调用。