大阿里的一道笔试题

2013年5月4日 由 Creater 留言 »

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

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

广告位

发表评论

你必须 登陆 方可发表评论.