Skip to content

析构函数

析构函数也是一个函数

  • 触发时机:在对象空间被销毁之前调用
  • 作用:释放资源,销毁堆内存

1.语法

与构造函数类似,析构函数的名称要和类名相同没有返回值不能有参数,但是函数名前要加~

c++
#include<iostream>
using namespace std;

class Person {
public:
	~Person() {
		cout << "析构函数被调用" << endl;
	}
};

int main() {
	Person p1;
	return 0;
}

image-20240718160547373

我们发现,我没没有手动释放内存空间,析构函数也被执行

因为我们在栈上定义数据时,栈会自动释放内存

而在堆中定义数据时,则不会

c++
#include<iostream>
using namespace std;

class Person {
public:
	~Person() {
		cout << "析构函数被调用" << endl;
	}
};

int main() {
	Person* p1 = new Person();
	return 0;
}

可以看到,没有手动释放内存,析构函数并没有执行

image-20240718160727423

而当我们手动通过delete把堆中数据删除时,析构函数才会执行

c++
#include<iostream>
using namespace std;

class Person {
public:
	~Person() {
		cout << "析构函数被调用" << endl;
	}
};

int main() {
	Person* p1 = new Person;
	delete p1;
	return 0;
}

image-20240718160916235

2.释放堆空间

我们在类中声明一个指针变量,并让它指向一个堆地址

发现,当我们手动delete对象后,该变量的值依然存在

c++
#include<iostream>
using namespace std;

class Person {
public:
	int* p;
	~Person() {
		cout << "析构函数被调用" << endl;
	}
};

int main() {
	Person* p1 = new Person;
	p1->p = new int(10);
	delete p1;

	cout << *p1->p << endl; // 10
	return 0;
}

这时就需要发挥析构函数的作用了

我们需要在析构函数中将堆中的数据释放,把指针变成空指针,并删除地址空间

nullptr相当于NULL,意为空指针

此时当释放内存后再访问堆中的数据,便会报错了

c++
#include<iostream>
using namespace std;

class Person {
public:
	int* p;
	~Person() {
		if (p != nullptr) {
			delete p;
			p = nullptr;
		}
	}
};

int main() {
	Person* p1 = new Person;
	p1->p = new int(10);
	delete p1;

	cout << *p1->p << endl; // 访问错误
	return 0;
}

MIT Licensed