龙空技术网

C++构造函数和析构函数的调用顺序,有什么规律?linux C++第36讲

韦凯峰Linux编程学堂 168

前言:

眼前小伙伴们对“构造函数何时被调用”可能比较关怀,小伙伴们都需要分析一些“构造函数何时被调用”的相关资讯。那么小编在网上搜集了一些关于“构造函数何时被调用””的相关资讯,希望小伙伴们能喜欢,咱们一起来了解一下吧!

调用构造函数 和 析构函数的顺序

在使用构造函数和析构函数的时候,需要特别注意对它们的调用时间和调用顺序,如下是一个例子:

可以看到,调用stud1, stud2对象的构造函数,然后,对象销毁的时候,调用他们的析构函数。如果再仔细观察,可以看到:调用析构函数的次序正好与调用构造函数的次序相反。那么,调用顺序如下:

stud1构造函数 à stud2构造函数 à stud2析构函数 à stud1析构函数。

所以,最先被调用的构造函数,其对应的析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用。

注意:先构造的后析构,后构造的先析构。相当于一个栈,先进后出。

上面曾提到:在一般情况下,调用析构函数的次序与调用构造函数的次序相反。这是对同一类存储类别的对象而言的。例如,上面程序中的stud1和stdu2是在同一个函数中定义的局部对象,它们的特性相同。按照“先构造的后析构,后构造的先析构”的原则处理。

但是,并不是任何情况下都是按照这一原则处理的。在学习C语言的时候,曾介绍过“作用域和存储类型”的概念,这些概念对于对象也是适用的。就是说,对象可以在不同的作用域中定义,可以有不同的存储类型。这些都会影响到构造函数和析构函数的调用时机。程序测试例子如下:

可以看到,name = wkf 这个对象先构造,但是,先析构了。这些就涉及到对象的定义和销毁的时机来定论的。

例如,在一个函数中定义了两个对象:

void func()

{

student stud1; //定义自动局部对象

static student stud2; //定义静态局部对象

......

}

在调用func()函数时,定义了stud1, stud2对象。那么,先调用stud1的构造函数,再调用stud2的构造函数。在func()调用结束时,stud1是要释放的,因为它是局部对象,所以,调用stud1的析构函数。而stud2是静态局部对象,在func()调用结束的时候并不释放,直到程序结束的时候,才撤销stud2对象,才执行它的析构函数。

所以,我们需要明白,对象与对象之间调用构造函数或者析构函数的顺序,没有任何规定。唯一的规则是:对象创建的时候,调用构造函数,对象销毁的时候,调用析构函数。

3 总结

本章我们学习了C++类的构造函数和析构函数,这个知识点非常重要,需要完全掌握。而且,每一个知识点的例子,都需要亲自运行代码,亲自验证程序的运行。分析C++类对象的构造函数和析构函数的执行流程。

自己亲自调试的代码,才可以完全掌握构造函数和析构函数的特性。那么,再设计程序的时候,才可以合理地设计C++类对象的创建和销毁。

如果学习过JAVA,可以知道JAVA一个很大的特性是:没有指针。JAVA的内存是动态回收,所以,JAVA没有所谓的内存溢出这个概念。很多服务器就是要JAVA来开发。但是,C++的运行效率更高,所以,很多大型的游戏还是使用C++开发。

那么,为了避免内存的溢出问题,就需要合理地设计对象的创建和销毁。那么,对象的创建和销毁就需要C++来的构造函数和析构函数来完成。所以,这个知识点非常的重要。

在Android系统的框架中,中间层使用C++来开发,中间层集成了各种服务,它们管理着各种APP程序的运行。所以,对内存的使用非常的严格。这个时候,就涉及到一个概念“智能指针”。通过智能指针,可以如同JAVA那样,自动回收内存。那么,这个智能指针也就需要用到构造函数和析构函数的知识。所以,本章的内容非常的重要。

这个在后续的C++开发杂谈中再介绍“智能指针”的知识,讲解一个智能指针存在的理由,以及怎么样设计一个智能指针类。

读者要仔细分析,掌握好每一个知识点,然后,自己总结出对该知识点的理解。自己总结出来的知识,理解才深刻,才是自己掌握的知识。

标签: #构造函数何时被调用 #java中构造函数何时被调用