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

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

继承

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

#include 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 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 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 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()

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

发布了282 篇原创文章 · 获赞 4 · 访问量 5544

猜你喜欢

转载自blog.csdn.net/it_xiangqiang/article/details/105233246
今日推荐