关于C++中析构函数和构造函数的调用时机:分情况讨论

一句话总结

构造函数和析构函数的调用时机:先构造的后析构,后构造的先析构,它相当于一个栈,先进后出。

但是,并不是在任何情况下都是按照上面的原则进行处理。对象可以在不同的作用域中定义,可以有不同的存储类别,这些都会影响调用构造函数和析构函数的时机。

几种调用时机的总结(看完实践下):

(0)在全局范围中定义的对象(即在所有函数之外定义的对象),它的构造函数在文件中的所有函数(包括main()函数)执行之前调用。但是如果一个程序中有多个文件,而不同的文件中都定义了全局对象,则这些对象的构造函数的执行顺序是不确定的。当main()函数执行完毕或调用exit函数时(此时程序终止),调用析构函数。

(1)如果定义的是局部自动对象(如在函数中定义对象),则在建立对象时调用其构造函数。如果函数被多次调用,则在每次建立对象时都要调用构造函数。在函数调用结束、对象释放时先调用析构函数。

(2)如果在函数中定义静态(static)局部对象,则只在程序第一次调用此函数建立对象时调用构造函数一次,在调用结束时对象并不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用析构函数。

下面是代码:

#include<iostream>
#include<stdlib.h>
using namespace std;

class test
{
public:
	test(int val):a(val)
	{
		cout << "Constructor called and a = " << a << endl;
	}

	~test()
	{
		cout << "Destructor called and a = " << a << endl;
	}

	int a;
};

void fun()
{
	// 定义自动局部对象,定义时执行构造函数,函数结束后释放,执行析构函数
	test a(300);

	// 定义静态局部对象,在函数第一次调用时执行构造函数,此后再次运行fun()函数,并不会调用构造函数
	// 函数结束后,并不释放,而是等到程序结束后,才执行析构函数
	static test b(400);
}

// 全局对象
test A(9999);

int main()
{
	//	自动局部对象 先构造,后析构
	test a(100);	

	//  自动局部对象 后构造,先析构
	test b(200);	

	// 第一次调用函数
	fun();

	// 第二次调用函数
	fun();

	return EXIT_SUCCESS;
}

以下是函数执行结果,慢慢品。。。
后面的注释和空格是我加上去的,并不是函数执行打印

// 全局对象在main函数执行之前,调用构造函数
Constructor called and a = 9999

// main函数中声明的对象依次执行构造
Constructor called and a = 100
Constructor called and a = 200

// 第一次执行fun函数,静态局部对象执行构造,但在函数结束后,并不执行析构
Constructor called and a = 300
Constructor called and a = 400
Destructor called and a = 300

// 第二次执行fun函数,静态局部对象不再执行构造,因为已经构造过了,函数结束后,仍不执行析构
Constructor called and a = 300
Destructor called and a = 300

// main函数结束,main函数中声明的对象依次执行析构,最后析构的是静态局部对象
Destructor called and a = 200
Destructor called and a = 100
Destructor called and a = 400

// 全局对象在main函数结束之后,调用析构函数
Destructor called and a = 9999

内容参考:《后台开发 核心技术与应用实践》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章