C++初学者指南 第十篇(8)

来源:互联网 发布:淘宝上便宜好用的口红 编辑:程序博客网 时间:2024/06/04 22:08
转载请标明出处:http://blog.csdn.net/zhangxingping

必备技能10.7:构造函数和析构函数在什么时候被执行?

基类可能含构造函数或者析构函数,派生类也可能含有构造函数或者析构函数,或者两者都有构造函数或者析构函数,此时理解这些构造函数和析构函数的执行顺序就是非常重要的了。具体来说,当一个派生类的对象被生成的时候,基类和派生类的构造函数是以什么样的顺序被调用的呢?当这个对象被销毁的时候,析构函数又是以什么样的顺序被调用的了。为了回答这些问题,我们来研究一下下面的这个程序:

#include <iostream>using namespace std;class B{public:    B()    {        cout << "Constructing base portion.\n";    }    ~B()    {        cout << "Desctructing base portion.\n";    }};class D : public B{public:    D()    {        cout << "Constructing derived portion.\n";    }    ~D()    {        cout << "Destructing derived portion.\n";    }};int main(){    D ob;    //do nothing    return 0;}


正如上面程序中的注释那样,这个程序只是简单的生成了一个名称为ob的对象,它是D类的一个对象,然后就销毁了该对象。执行该程序时,输出如下:

Constructing base portion.

Constructing derived portion.

Destructing derived portion.

Desctructing base portion.

如程序输出的那样,首先是B类的构造函数被执行,接着执行D类的构造函数。再接着,D的析构函数被调用,最后是B的析构函数被调用。

从上面程序的经验来看,我们可以总结如下:当派生类的对象被创建的时候,首先调用的是基类的构造函数,然后调用派生类的构造函数。当派生类的对象被销毁的时候,派生类的析构函数先被调用,然后基类的析构函数才被调用。换句话说,构造函数的调用顺序和继承关系保持一致,而析构函数的调用则恰好相反。在多层次的继承关系中,同样的规则也适用:构造函数的调用顺序和继承关系保持一致,而析构函数则恰好相反。当一个类继承了多余一个基类的时候,构造函数的调用顺序则是按照基类继承列表中从左到右的顺序进行的,而析构函数的调用顺序则是相反的,从右到左进行的。

练习:

1. 一个派生类可否作为另外一个派生类的基类?

2. 在类的继承关系中,构造函数的调用顺序如何?

3. 在类的继承关系中,析构函数的调用顺序如何?

专家答疑

问:为什么构造函数的调用顺序是以继承的关系为准,而析构函数则是以相反的顺序被调用?

答:如果我们仔细考虑一下,构造函数是按照继承的顺序来来调用的,这样是有道理的。因为基类是感知不到派生类的。基类所要进行的初始化操作是和派生类要进行的操作完全分开的,而且还有可能是派生类进行初始化的前提。因此,基类的构造函数必须首先被调用。

同样的道理,析构函数是以与继承关系相反的顺序被调用也是有道理的。既然基类是派生类的基础,基类的销毁就意味着派生类的销毁。因此,派生类的析构函数必须在派生类的对象被完全销毁前就被调用。