析构函数

对象销毁,会自动调用析构函数。

因此,绝不可以自行调用析构函数,因为对象还没有销毁,其他人可能还在使用该对象。再者,由于对象销毁会自动调用析构函数,这就出现了double free 错误。

如果我们没有定义析构函数,系统默认会给此类定义一个默认的析构函数。

当数据成员中有指针时,创建一个对象,会申请堆空间,销毁对象时默认析构不够用了(造成内存泄漏),此时就需要我们自定义析构函数。在析构函数中定义堆空间上内存回收的机制,就不会发生内存泄漏。

如下图中 _brand 是 Computer 类的成员变量,并且在构造函数中申请堆内存初始化(图中没有体现)。等到对象销毁的时候,析构函数的工作就是要回收掉自己的成员变量的堆内存。

000析构函数.png

  1. 对于全局对象整个程序结束时,自动调用全局对象的析构函数。
  2. 对于局部对象,在程序离开局部对象的作用域时调用对象的析构函数。
  3. 对于静态对象,在整个程序结束时调用析构函数。
  4. 对于堆对象,在使用 delete 删除该对象时,调用析构函数。

 

最后一条极其核心,重点要进行说明。

我们自定义的析构函数是回收自己类中的成员变量,通过 delete 去回收 拥有堆内存的成员变量。但是它不具备 delete 自身的能力,因此我们讲 使用者创建该对象之后(堆上的对象),记得 delete 掉。

001析构函数.png

注意看图中对 p2 指针对象的处理,由于它是堆内存,对象本身的析构函数不会销毁自己,需要生成者自行 delete。delete 之后,记得置为 nullptr。

那么 delete 对象究竟干了什么?调用该对象的析构函数,然后回收对象本身的内存空间。

后面学习智能指针就更方便,它会自动将管理的对象,在对象销毁之后,自动 delete 掉该对象。注意析构函数不是智能指针调用的,而是对象本身销毁之后自己会调用,但是对象本身的堆内存 delete 会由智能指针完成。