析构函数
#CPP
2024-10-31
对象销毁,会自动调用析构函数。
因此,绝不可以自行调用析构函数,因为对象还没有销毁,其他人可能还在使用该对象。再者,由于对象销毁会自动调用析构函数,这就出现了double free 错误。
如果我们没有定义析构函数,系统默认会给此类定义一个默认的析构函数。
当数据成员中有指针时,创建一个对象,会申请堆空间,销毁对象时默认析构不够用了(造成内存泄漏),此时就需要我们自定义析构函数。在析构函数中定义堆空间上内存回收的机制,就不会发生内存泄漏。
如下图中 _brand 是 Computer 类的成员变量,并且在构造函数中申请堆内存初始化(图中没有体现)。等到对象销毁的时候,析构函数的工作就是要回收掉自己的成员变量的堆内存。
- 对于全局对象,整个程序结束时,自动调用全局对象的析构函数。
- 对于局部对象,在程序离开局部对象的作用域时调用对象的析构函数。
- 对于静态对象,在整个程序结束时调用析构函数。
- 对于堆对象,在使用 delete 删除该对象时,调用析构函数。
最后一条极其核心,重点要进行说明。
我们自定义的析构函数是回收自己类中的成员变量,通过 delete 去回收 拥有堆内存的成员变量。但是它不具备 delete 自身的能力,因此我们讲 使用者创建该对象之后(堆上的对象),记得 delete 掉。
注意看图中对 p2 指针对象的处理,由于它是堆内存,对象本身的析构函数不会销毁自己,需要生成者自行 delete。delete 之后,记得置为 nullptr。
那么 delete 对象究竟干了什么?调用该对象的析构函数,然后回收对象本身的内存空间。
后面学习智能指针就更方便,它会自动将管理的对象,在对象销毁之后,自动 delete 掉该对象。注意析构函数不是智能指针调用的,而是对象本身销毁之后自己会调用,但是对象本身的堆内存 delete 会由智能指针完成。