析构函数也是一个特殊的成员函数,它的作用刚好和构造函数相反,它的名字是类名的前面加一个"~"符号
析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前完成一些清理工作,使这部分内存可以被程序分配给新对象使用。而且作用不仅可以用来释放资源,还可以被用来执行 用户希望在最后一次使用对象之后所执行的任何操作。
析构函数不返回任何值,没有函数类型,也没有函数参数。没有函数参数,所以它不能被重载。一个类可以有多个构造函数但只能有一个析构函数。
程序设计者需要预先设计好析构函数,已完成所需的功能。只要对象的生命期结束,程序就自动执行析构函数来完成这些工作。
一般情况下,用户应当在类的声明的同时定义析构函数,以指定如何完成”清理“的工作,如果用户没有定义析构函数,c++编译系统会自动生成一个析构函数,但它只是徒有析构函数的名称和形式,实际上什么操作都i不进行,想让析构函数完成任何工作,都必须在定义的析构函数中指定。构造函数
#include<iostream>
#include <string>
using namespace std;
class Student
{
public:
Student()
{
name = "zhangsan";
age = 23;
sex = 'T';
}
Student(string nam, int a, char s) :name(nam), age(a), sex(s)
{}
void display();
~Student();
private:
string name;
int age;
char sex;
};
void Student::display()
{
cout << "name:" << name << endl;
cout << "age:" << age << endl;
cout << "sex:" << sex << endl;
}
Student::~Student()
{
cout << "name:" << name << endl;
}
int main()
{
//自动局部对象:当一个函数中定义了该对象,当该函数调用结束了,对象应该释放,在对象释放前,自动执行析构函数
Student st1;
Student st2("yangxiao",34,'T');
return 0;
}
这个代码中定义了一个无参构造函数和一个带有三参构造函数,并定义了一个析构函数,该析构函数体中是输出对应的name的内容,因为所以在不同的对象进行析构的时候,会输出不同的结果,最终我们发现运行结果是:
yangxiao
zhangsan
为什么和我们想的不一样呢?因为调用析构函数的次序正好与调用构造函数的次序相反,先构造的后析构,后构造的先析构。
构造函数执行顺序:
- 如果在全局范围内定义对象,(在所有函数之外定义对象),那么它的构造函数在本文件模块中的所有函数(包括main函数)执行之前调用。如果一个程序包含多个文件,而在不同的文件都定义了全局对象,则这些对象的构造函数的执行顺序是不确定的,当main函数执行完,或调用exit函数时,才执行析构函数。
- 如果定义的是局部自动对象,则在建立对象时调用其构造函数,如果对象所在函数被多次调用,则在每次建立对象的时候都要调用构造函数,函数调用 结束、对象释放的时候先调用析构函数。
- 如果定义的对象是静态局部对象,则只在程序第一次调用此函数定义对象时调用构造函数,在调用函数结束时,对象并不释放,因此也不调用析构函数,只有main函数或调用exit函数结束程序时,才调用析构函数
析构函数执行顺序:
- 如果在一个函数中定义了一个局部对象,当函数调用结束时,此时系统自动调用析构函数
- 静态局部对象所在的函数在调用结束之后并不释放对象,因此也不调用析构函数,只有当main函数结束或者调用exit函数结束程序时,才调用static局部对象的析构函数。
- 如果定义了一个全局的对象,则在程序的流程离开其作用域时(main函数结束时或调用exit函数),调用全局的对象的析构函数
- 如果调用new运算符动态的建立了一个对象,当用delete运算符释放该对象时,先调用该对象的析构函数。