构造函数和析构函数的调用过程
B、~B ~A
C、~B ~A ~A
D、~B ~A ~A ~A
been:
B(A &a):_a(a)
这个引用也是值得注意的,这里提醒大家一下,去掉引用,第一个析构是是~A
灵灵:
下面以例子说明参数为类对象,是否有初始化列表时构造与析构函数的执行顺序:
vzhuzhu:
对于构造函数:基类构造函数 > 子类成员变量构造函数 > 子类构造函数
对于析构函数:子类析构函数 > 子类成员变量析构函数 > 基类析构函数
可以看出构造函数的调用过程和析构函数的调用过程正好相反。
水泽渊:
在vs上运行之后发现,输出顺序确实如@Aesthetic92所说,然而@赖聪林说的也没有错,可是@赖聪林举的例子并没有用到拷贝构造函数。
原题-----------------------------------------------------------------------------
加上拷贝构造函数---------------------------------------------------------------------- <pre name="code" class="cpp"> class A { public: A(){ cout<<"A"<<endl; } A(const A& other){ cout<<"copy A"<<endl;} ~A() { cout<<"~A"<<endl; } }; class B:public A {public:B(A &a):_a(a) {cout<<"B"<<endl; } ~B() { cout<<"~B"<<endl; } private: A _a; }; void main(void) {A a; B b(a);} //结果显示 A A copy A B ~B ~A ~A ~A
修改后---------------------------------------------------------------------------------- class A {public: A() { cout<<"A"<<endl; } A(const A& other){ cout<<"copy A"<<endl;} ~A() { cout<<"~A"<<endl; } };class B:public A {public:B(A &a) { cout<<"B"<<endl; } ~B() { cout<<"~B"<<endl; }private: A _a; };voidmain(void){ A a; B b(a);} //结果为 A A A B ~B ~A ~A ~A
答案:选D
答案解析:答案看起来可能比较怪,其实给默认构造函数补上输出,然后再在基类里写个复制构造函数,这样结果就很明朗了;
首先 A a;这个调用A的默认构造函数,
B b(a); 因为A &a,形参为引用,不需要调用基类复制构造函数(其实基类也没写);_a(a)首先创建对象_a,调用基类A的默认构造函数,然后调用基类复制构造函数(测试的时候可以写出来),把a对象赋给_a,结束之后调用B的析构函数,输出~B;然后调用基类A的析构函数撤销复制构造函数,输出~A;调用基类A的析构函数撤销_a,输出~A;最后调用基类A的析构函数撤销一开始创建的A a,输出~A
kuring:
要想搞明白该问题,需要理解基类构造析构函数、子类构造析构函数和子类成员变量构造析构函数的调用顺序。
对于构造函数:基类构造函数 > 子类成员变量构造函数 > 子类构造函数
对于析构函数:子类析构函数 > 子类成员变量析构函数 > 基类析构函数
可以看出构造函数的调用过程和析构函数的调用过程正好相反。
main函数中首先构造变量a,然后是b。在构造b时首先调用b的基类A的构造函数,然后调用b中成员变量_a的构造函数,最后调用b的构造函数。
main函数调用结束返回时,变量的释放顺序跟变量的构造顺序正好相反。首先释放变量b,然后是变量a。
在释放变量b时,首先调用b的析构函数,然后析构变量b的成员_a,析构_a时调用_a的析构函数。再调用b的基类的析构函数。
然后是释放变量a,调用a的析构函数。
本例子中应该将A的析构函数更改为virtual的,防止使用多态机制时出现子类对象无法释放的情况,本例子中没有用到多态机制,不存在该问题。
赖聪林:
我们可以看到,这个地方先是调用parent class的构造函数,然后对成员变量C类型的构造函数,然后再最后执行B类型的构造函数。
析构的过程就是上面的过程反过来。
所以Aesthetic92的解释有一部分不是很准确。我认为。
更加准确的说明应该是,
最开始析构b,~B,这个是没有争议的。
接着是析构b的成员变量_a,所以是~A
接着是b的parent class(基类)的~A
最后才是a的析构~A
不过为了理解这道题,我感觉配上我的例子更好理解一点,原题的成员变量和基类都是相同的类型,比较难以辨认。
总结
以上是生活随笔为你收集整理的构造函数和析构函数的调用过程的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 右左法则----复杂指针解析
- 下一篇: 部分真题整理2