首页 > 其他 > 详细

一道超经典且易错的笔试题

时间:2015-01-27 13:23:41      阅读:231      评论:0      收藏:0      [点我收藏+]
#include<iostream>
using namespace std;
class A  
{  
public:  
    A()  {    cout<<"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;  
};  
  
int main(void)  
{  
    A a;       //很简单,定义a的时候调用了一次构造函数  
    B b(a);    //这里b里面的_a是通过成员初始化列表构造起来的  
    //而且是通过copy constructor构造的是b的成员对象_a的,这里是编译器默认的,因此在构造好_a前,先调用基类构造函数  
    //然后才是构造自身,顺序就是A()->_a->B()(局部)  
    //因此这里有两个A,一个B  
    //在return之前进行析构  
    /************************************************************************/  
    /*析构是按照定义对象的反顺序来的,而且同一个对象按照构造的反顺序来的,因此这里先 
    析构b然后才是a,那么b的构造顺序是上面的A()->_a->B()(局部),反过来,就是B()(局部)->_a->A() 
    因此得到的就是~B->~A->~A 
    在b之后就是析构a 
    最后结果就是 
    ~B->~A->~A->~A*/  
    return 0;  

}  

此题的答案为:

A

A

B

~B

~A

~A

~A

仔细发现你可能会看出来多析构了一次A,其实在B b(a);  时,先调用了一次A构造函数,然后通过copy constructor构造b的成员对象_a(看清楚_a是一个A对象,并不是普通数据成员),由于没有显示声明A的默认拷贝构造函数,就默认调用编译器提供的默认拷贝构造函数。最后调用B的构造函数。

若将类A改成:

class A  
{  
public:  
        A()  {    cout<<"A"<<endl;    }  
        A(A &temp)
        {
            printf("A copy create!\n");
        }
    ~A() {    cout<<"~A"<<endl;   }  
};  

那么结果为

A

A

A copy create!

B

~B

~A

~A 

~A

一道超经典且易错的笔试题

原文:http://blog.csdn.net/u014082714/article/details/43193007

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!