C++类与对象总结(三)析构函数

析构函数Destructor

析构函数与构造函数相似,都是特殊的成员函数。不同在于构造函数用于对象的初始化,析构函数用于对象的清理工作。 名称为~加类的名称,不可以重载,无返回类型。

1
2
3
4
5
6
7
8
class A
{
private:
int a;
public:
A():a(10){} //A的构造函数
~A(){} //A的析构函数
}

与构造函数相似,如果我们没有定义析构函数,编译器会自动生成一个什么都不做的析构函数。

析构函数的调用时机

  • 栈中定义的对象,离开作用域前或程序结束前调用。
  • 堆中定义的对象,在delete时调用。

析构的顺序

对于栈中直接定义的对象,析构顺序由构造顺序决定。顺序是一种栈的思想,先构造的对象后析构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;

class A
{
private:
int a;
public:
A(int i):a(i)//A的构造函数
{
cout << a << " Constructor" << endl;
}
~A()//A的析构函数
{
cout << a << " Destructor" << endl;
}
};

int main()
{
A a(1);
A b(2);

return 0;
}

输出信息为:

1
2
3
4
1 Constructor
2 Constructor
2 Destructor
1 Destructor

可以看出它是一种“先进后出”的顺序去构造和析构。 对于没有构造的对象,不会进行析构

delete与delete[]

1
2
3
4
int *p = new int[10];

delete p;
delete[] p;

对于上面代码中基础数据类型的数组的回收空间来说,后面两行的delete效果是一样的。 但如果是用户定义的类型就会有所不同。

1
2
3
4
A *p = new A[10];

delete p;
delete[] p;

像这样的情况下,第三行的delete和第四行的delete[]都会回收new时分配的空间,但第三行的delete只会调用一次A的析构函数,而第四行的delete[]会调用10次A的析构函数。 delete和delete[]都会回收空间,但delete[]会逐个调用每个对象的构造函数。特别是对于成员函数中有new操作的类来说,必须在析构函数中去delete,delete时要注意区分delete和delete[],否则可能会造成内存泄漏。

本文标题:C++类与对象总结(三)析构函数

文章作者:赵砚潇

发布时间:2018年03月07日 - 00:03

最后更新:2018年07月05日 - 01:07

原始链接:https://blog.zyx.sh/2018/03/07/cpp-class-3/

许可协议: 署名-非商业性使用-相同方式分享 4.0 国际 转载请保留原文链接及作者。

Donate comment here