更多课程 选择中心

C/C++培训
达内IT学院

400-996-5531

C++构造及析构函数执行顺序

  • 发布:C++培训
  • 来源:资料库
  • 时间:2017-10-16 13:26

前不久,一个朋友面腾讯社招的后台开发岗,和他聊了聊,他说腾讯的一面还是比较重基础的,C++,操作系统,网络、算法这块问的比较多,即便是社招。其中就有一个C++牵涉到虚拟继承时其构造和析构顺序的题目,这个平时也不太注意,因此也真难住了不少面试者,我那位朋友就是其一,因此有必要总结下。

在C++中,当创建一个类对象时,编译器是会自动调用一个叫构造函数的东西的,我们知道,C++类与类之间很多情况下是有关联的,比如继承,组合等等。本文主要通过实例总结各种情况下的构造与析构顺序。

继承

场景:B类继承两个父类A和C,每个类的构造函数和析构函数很简单,就是打印对应的函数名,以便观察构造及析构函数执行顺序。

#include <iostream>using namespace std;class A{ public: A(){cout << "A()" << endl;} ~A(){cout << "~A()" << endl;}};class C{ public: C(){cout << "C()" << endl;} ~C(){cout << "~C()" << endl;}};class B: public A, public C{ public: B(){cout << "B()" << endl;} ~B(){cout << "~B()" << endl;}};int main(int argc, char const *argv[]){ B b; return 0;}

bogon:dataStructure lizhong$ ./tA()C()B()~B()~C()~A()

通过运行结果可以看出:创造一个子类对象时,先执行父类的构造函数,再执行自身的构造函数,如果子类继承多个父类,则按照继承的顺序从左到右调用父类构造函数(本例先构造A,再构造C),析构的顺序与构造的顺序相反。

我们还知道还有一种继承叫做虚拟继承,看看这种情况下的构造与析构又是怎样的顺序。

#include <iostream>using namespace std;class A{ public: A(){cout << "A()" << endl;} ~A(){cout << "~A()" << endl;}};class C{ public: C(){cout << "C()" << endl;} ~C(){cout << "~C()" << endl;}};class B: public A, public C{ public: B(){cout << "B()" << endl;} ~B(){cout << "~B()" << endl;}};int main(int argc, char const *argv[]){ B b; return 0;}

bogon:dataStructure lizhong$ ./tC()A()B()~B()~A()~C()

可以看出:虚拟继承和一般的继承构造和析构的顺序还是有点不一样,父类的构造顺序发生了改变,虚拟继承的C构造函数先被执行,然后是A。最后是自身的构造函数被调用,析构的顺序与构造的顺序相反。

成员包含其它类对象成员

场景:B类含有A类对象和C类对象的成员,且在B类中,其成员声明顺序是先声明c,再声明a。看看创造B类对象时,构造函数和析构函数的执行顺序是怎样的。

#include <iostream>using namespace std;class A{ public: A(){cout << "A()" << endl;} ~A(){cout << "~A()" << endl;}};class C{ public: C(){cout << "C()" << endl;} ~C(){cout << "~C()" << endl;}};class B{ public: B():a(A()), c(C()) {cout << "B()" << endl;} ~B(){cout << "~B()" << endl;} C c; A a;};int main(int argc, char const *argv[]){ B b; return 0;}

bogon:dataStructure lizhong$ ./tC()A()B()~B()~A()~C()

运行结果可以看出:创造一个B类对象b时,先执行其成员对象所属类的构造函数,再执行自身的构造函数,如果有多个类对象成员,则按照声明的顺序调用对应类的构造函数(本例先构造C类对象c,再构造A类对象a),析构的顺序与构造的顺序相反。

即有继承又包含类对象成员

场景:B类继承两个父类A和C,并且B类有一个X类的对象成员,观察构造及析构函数执行顺序。

#include <iostream>using namespace std;class A{ public: A(){cout << "A()" << endl;} ~A(){cout << "~A()" << endl;}};class C{ public: C(){cout << "C()" << endl;} ~C(){cout << "~C()" << endl;}};class X{ public: X(){cout << "X()" << endl;} ~X(){cout << "~X()" << endl;}};class B: public A, public C{ public: B(){cout << "B()" << endl;} ~B(){cout << "~B()" << endl;} X x;};int main(int argc, char const *argv[]){

B b;

return 0;}

bogon:dataStructure lizhong$ ./tA()C()X()B()~B()~X()~C()~A()

运行结果可以看出:类在构造的时候会先从左到右调用父类的构造函数,然后调用类对象成员构造函数,最后调用自身构造函数。析构的顺序与构造的顺序相反。

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:QML界面与C++逻辑分离的一次小尝试
下一篇:C/C++开发过程中的头文件规整

超全的C语言标识符知识

C指针——指针类型转换

C指针——指针和结构类型的关系

C指针——数组和指针的关系

Copyright © 2023 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省