C++之------------析构函数

析构函数

参考链接

参考链接

什么是析构函数

析构函数为成员函数的一种,名字与类名相同,在前面加‘~’没有参数和返回值在C++中“~”是位取反运算符。
一个类最多只能有一个析构函数。析构函数不返回任何值,没有函数类型,也没有函数参数,因此它不能被重载。

构造函数可能有多个,但析构函数只能有一个,就像人来到人世间,可能出生的环境家庭不同(重载构造函数),但最终都会死亡(析构函数)

什么时候会调用析构函数

(1)如果在一个函数中定义了一个对象(它是自动局部对象),当这个函数被调用结束时,对象应该释放,在对象释放前自动执行析构函数。
(2)static局部对象在函数调用结束时对象并不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用static局部对象的析构函数。
(3)如果定义了一个全局对象,则在程序的流程离开其作用域时(如main函数结束或调用exit函数) 时,调用该全局对象的析构函数。
(4)如果用new运算符动态地建立了一个对象,当用delete运算符释放该对象时,先调用该对象的析构函数。
(5)调用复制构造函数后。

构造函数的调用:
(1)全局变量:程序运行前;
(2)函数中静态变量:函数开始前;
(3)函数参数:函数开始前;
(4)函数返回值:函数返回前;
析构函数的调用:
(1)全局变量:程序结束前;
(2)main中变量:main结束前;
(3)函数中静态变量:程序结束前;
(4)函数参数:函数结束前;
(5)函数中变量:函数结束前;
(6)函数返回值:函数返回值被使用后;

继承构造与析构

对于相同作用域和存储类别的对象,调用析构函数的次序正好与调用构造函数的次序相反

这里涉及到构造以及析构的顺序,首先看看构造。**构造函数执行的顺序是,先构造父类,再构造子类,其中父类的构造顺序是从左到右。**然后析构函数执行的顺序是跟构造函数正好相反的,先执行自身的析构函数,然后再依次从右到左执行父类的析构函数。

列表初始化成员变量

	#include <iostream>
	#include <cmath>
	using namespace std;

	class A
	{
	public:
		A(){cout << "Construct A" << endl;}
		~A(){cout << "Destruct A" << endl;}
	};

	class C
	{
	public:
		C(){cout << "Construct C" << endl;}
		~C(){cout << "Destruct C" << endl;}
		
	};

	class B
	{
	public:
		// Notice
		B(): a(A()), c(C()) {cout << "Construct B" << endl;}
		~B(){cout << "Destruct B" << endl;}
		C c;
		A a;
	};

	int main(int argc, char const *argv[])
	{
		B b;
		return 0;
	}

结果

	Construct C
	Construct A
	Construct B
	Destruct B
	Destruct A
	Destruct C

可以看出,列表初始化是先于构造函数的调用的,而且列表初始化是与初始化顺序无关,只与数据成员定义的顺序有关。在上面的例子中C类型的变量定义在A类型的变量前面,因此会先构造C,之后构造A。

结论

在类被构造的时候,先执行虚拟继承的父类的构造函数,然后从左到右执行普通继承的父类的构造函数,然后按照定义的顺序执行数据成员的初始化,最后是自身的构造函数的调用。析构函数与之完全相反,互成镜像。

#include <printf.h>

#include <iostream>
using namespace std;

class A {
 public:
  A() { cout << "A" << endl; }
  ~A() { cout << "~A" << endl; }
};

class B : public A {
 public:
  B(A& a) : a_(a) { cout << "B" << endl; }
  ~B() { cout << "~B" << endl; }

 private:
  A a_;
};

int main() {
  A a;
  B b(a);
  return 0;
}

输出

A
A
B
~B
~A
~A
~A

解释:

​ 构造的时候先构造父类A再开始构造子类B的参数列表A,因为是移动构造所以并没有产生副本最后构造B,所以构造的顺序就是: A A B

​ 析构正好相反

​ 先析构子类,再析构子类的参数列表最后析构父类

​ 所以析构就是 ~B ~A ~A ~A

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值