析构函数是与构造函数对立的函数
析构函数与构造函数的区别
构造函数 | 析构函数 |
返回值是创建的对象(不写返回值) | 无返回值 |
手动调用,并创建对象 | 当对象销毁时,自动调用 |
函数名称是类名 | 函数名称是~类名(类名取反) |
有参数 | 无参数 |
支持重载和默认值 | 不支持 |
不能设置为虚函数 | 可以设置为虚函数 |
一个析构函数调用的例子
#include <iostream>
using namespace std;
class Cat
{
private:
string name;
public:
Cat(string n) // 构造函数
{
name = n;
}
~Cat() //析构函数
{
cout << name << "调用析构函数" << endl; //为了观察到何时调用
}
};
int main()
{
cout << "主函数开始" << endl;
// 独立(局部)代码块:表示一个局部范围
{
Cat a("A"); // a生命周期仅在27-30行
Cat* c = new Cat("C"); //此处只有new,无delete,故c不会调用析构函数
}
//独立代码块结束时会调用析构函数
Cat b("B");
Cat* d = new Cat("D");
delete d;
cout << "主函数结束" << endl;
return 0;
}
// 生命周期结束以后,局部变量才会被销毁
运行结果
主函数开始
A调用析构函数
//C未调用析构函数
D调用析构函数
主函数结束
B调用析构函数
深拷贝内存泄漏解决方案
public:
Dog(char* n)
{
//开启一个堆内存区域
name = new char[20]; // 创建一个char类型数组对象,让name去指向独享区
strcpy(name, n); // 拷贝数据
}
Dog(const Dog& d)
{
//开启一个堆内存区域
name = new char[20]; // 创建一个char类型数组对象,让name去指向独享区
strcpy(name, d.name); // 拷贝数据
}
~Dog() //析构函数(仅需一个)
{
delete name; //因为析构函数不能重载,以上俩new无论那个结束,都会通过此析构函数
}