C++析构函数
析构函数是类的另一个特殊成员函数,它的作用与构造函数相反,C++规定析构函数的名字是类的前面加上一个波浪号(~):
~类名()
{
函数体
}
析构函数不返回任何值,没有返回类型,也没有函数参数。由于没有函数参数,因此它不能被重载。换言之,一个类可以有多个构造函数,但是只能有一个析构函数。
(一)何时调用析构函数
当对象的生命周期结束时,撤销类对象时候会自动调用析构函数。
1)对象在生命期结束,撤销类对象时会自动调用析构函数。
如果在一个函数中定义了一个非静态局部对象,那当函数调用结束时候,对象被释放,在对象被释放前调用析构函数。
函数中的静态局部对象在函数调用结束时候对象并不释放,因此不调用析构函数。静态局部对象或全局作用域的对象只有在主函数结束时候,才会调用析构函数。
2)如果用new运算动态地建立一个对象,那用delete运算符释放该对象时,才会调用析构函数。
这种方式不以作用域范围为对象的生命期,而是以执行new和delete运算区间为生命期,因此这种方式可以跨越多个函数作用域。需要注意,尽管动态对象可以跨作用域范围,保存动态对象的指针变量确实以作用域范围为声明周期的。
动态对象的指针即使超出其作用域,也不会自动调用对象的析构函数,只有在指向该对象的指针被delete时才撤销。如果没有delete指向动态对象的指针,对象就一直存在,导致内存泄漏,对象内部使用的任何资源也不会释放。
(二)合成析构函数
编译器总是会为类生成一个析构函数,称为合成析构函数。合成析构函数按照对象创建时的逆序来撤销每个非静态成员,即它是按照成员在类中声明的次序来撤销成员的。对于类类型的每个成员,合成析构函数调用该成员的析构函数来撤销对象。
需要注意,合成析构函数并不删除指针成员所指向的对象,他需要程序员显示地编写析构函数去处理。
(三)何时需要编写析构函数
许多类不需要显式编写析构函数。析构函数通常用于释放在构造函数或在生命期内获得的资源(如动态分配的内存)。广义上讲,析构函数的作用并不仅仅限于释放资源方面,它可以执行任意操作,用来执行“对象即将被撤销之前程序员所期待的任何操作。
如果类需要析构函数,则该类几乎必然需要定义自己的复制构造函数和赋值运算符重载,这个规则称为析构函数三法则。原因是如果类真的需要析构函数,则类中必然出现了指针类型成员且分配了资源(否则使用合成析构函数就可以了)同时,有指针类型的成员,应该尽可能防止浅复制。所以,一定需要复制构造函数和赋值运算符重载,这两个函数是防止浅复制所必需的。
(四)构造函数与析构函数调用次序
先构造的后析构,后构造的先析构。