一、概念
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作
。
二、特征
析构函数是特殊的成员函数,其特征如下:
1. 析构函数名是在类名前加上字符 ~。
2. 无参数无返回值类型。
3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载。
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。 (出了作用域自动调用)
三、下面用代码测试一下:
class Data
{
public:
Data(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
// 不需要写,默认生成的就够用,但是默认生成的也没做什么事情
// 因为 year month day 都是在栈上开辟,函数调用结束就自己返还给操作系统,不需要自己去释放
//~Data() // 析构函数
//{
// // ~Data() 没有需要清理
// cout << "~Data()" << endl; // 虽然没用需要清理 但看是否会调用 ~Data() 函数
//}
private:
int _year = 1;
int _month = 1;
int _day = 1;
};
typedef int DataType;
class Stack
{
public:
Stack(size_t capacity = 3)
{
_array = (DataType*)malloc(sizeof(DataType) * capacity);
if (NULL == _array)
{
perror("malloc申请空间失败!!!");
exit(-1);
}
_capacity = capacity;
_size = 0;
}
void Push(DataType data)
{
_array[_size] = data;
_size++;
}
// 需要显示写 手动释放资源
~Stack() // 析构函数
{
free(_array);
_capacity = _size = 0;
_array = nullptr;
}
private:
DataType* _array;
int _capacity;
int _size;
};
class MyQueue {
public:
void push(int x) {}
// ...
// 不需要写,默认生成的就够用,但是默认生成对于 Stack 自定义成员,调用 Stack 析构函数
private:
size_t _size = 0;
Stack _st1;
Stack _st2;
};
void fun()
{
//Data d1; // 打印了 ~Data()
//Stack st;
MyQueue q;
}
int main()
{
fun();
return 0;
}
所以根据上面测试的代码可知:
默认生成析构函数特点:跟构造函数类似:a.内置类型不处理 ;b.自定义类型成员回去调用他的析构。
如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如
Date
类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack
类。