• 欢迎浏览“String me = Creater\忠实的资深Linux玩家;”,请文明浏览,理性发言,有侵犯你的权益请邮件我(creater@vip.qq.com).
  • 把任何的失败都当作一次尝试,不要自卑;把所有的成功都想成是一种幸运,不要自傲。
  •    5年前 (2013-05-04)  笔试面试 |   2 条评论  18 
    文章评分 0 次,平均分 0.0

    C++里对象构造时,内部的构造顺序这个很重要,一般有点C++基础的人都会知道。但是,但是有时候会另你防不胜防。来看看大阿里....

    #include <iostream>
    #include <typeinfo>
    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;
        B b(a);
    }

    这个题目的输出为?同学将这道题发我的时候,我做的也比较粗心,结果当然错了。
    我给的答案是

    A
    A
    B
    ~B
    ~A
    ~A
    

    我的想法是:
    首先A a,构造A这个对象,会调用A的构造函数,输出'A'
    接着执行 B b(a),派生类对象构造时先调用基类构造函数来初始化派生类对象的基类部分,所以输出‘A’
    接着继续B对象的构造,所以输出‘B’
    至此,a,b对象已经构造完成。

    释放呢?
    首先释放派生类对象的派生类部分,输出‘~B’
    接着释放派生类对象的基类部分,输出“~A'
    接着释放a这个对象,输出‘~A’

    实际上答案是,如下:

    A
    A
    B
    ~B
    ~A
    ~A
    ~A
    

    这是为什么呢?原因就是太粗心没看见类B有个私有成员 A _a; 说到这里,可能已经知道为什么了,不过还是写一下。
    构造过程:
    首先A a,定义对象a,会调用基类A的默认构造函数,输入‘A’
    接着B b(a),这个时候会执行B的拷贝构造函数,但是在执行函数体之前,还有重要的工作要做。第一是初始化派生类对象的基类部分,第二调用a的拷贝构造函数构造_a(这里就是最关键的地方),因为A类没有定义拷贝构造函数,所以编译器默认生成的没有输出。
    接着继续构造B,输出‘B’

    释放过程:
    首先释放派生类对象的派生类部分,输出‘~B’
    接着清理派生类对象的基类部分,输出‘~A’
    另外编译器还要进行默认的清理工作,清理_a对象,输出‘~A’
    最后清理a对象,输出'~A'

    如果我们自己定义A的拷贝构造函数,就完全明白了

    #include <iostream>
    #include <typeinfo>
    using namespace std;
    
    class A  
    {  
    public:  
        A()  {    cout<<"A"<<endl;    }  
    		A(const A& tA) {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;  
    };  
      
    int main(void)  
    {  
        A a;       //很简单,定义a的时候调用了一次构造函数  
        B b(a);    //这里b里面的
    }

    输出:(注意一点就是:先生成B对象,再构造_a,因为构造B对象会先申请空间,空间分配好以后,私有成员_a才可以构造)

    A
    A
    Copy A
    B
    ~B
    ~A
    ~A
    ~A
    

    主要是要细心,其他没什么说得。。。。

     

    除特别注明外,本站所有文章均为String me = "Creater\忠实的资深Linux玩家";原创,转载请注明出处来自http://unix8.net/home.php/1030.html

    关于

    发表评论

    暂无评论

    切换注册

    登录

    忘记密码 ?

    切换登录

    注册

    扫一扫二维码分享