首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

早上的一个笔试题目解决方案

2012-02-24 
早上的一个笔试题目#includeiostreamusingnamespacestdclassA{protected:intm_datapublic:A(intdata0

早上的一个笔试题目
#include   <iostream>
using   namespace   std;

    class   A          
    {      
    protected:
    int   m_data;
    public:          
    A(int   data   =   0){m_data   =   data;           }
    int   GetData(){return   doGetData();}
    virtual       int       doGetData(){     return   m_data;}          
    };          
       
    class   B:public       A          
    {          
        protected:
    int   m_data;
    public:          
    B(int   data   =   1){m_data   =   data;           }          
       
    int   doGetData(){     return   m_data;}          
    };    

    class   C:public   B
        {          
        protected:
    int   m_data;
    public:          
    C(int   data   =   2){m_data   =   data;           }        
    };


int   main()
{
C   c(10);

cout < <c.GetData() < <endl;
cout < <c.A::GetData() < <endl;
cout < <c.B::GetData() < <endl;
cout < <c.C::GetData() < <endl;
cout < <c.doGetData() < <endl;
cout < <c.A::doGetData() < <endl;
cout < <c.B::doGetData() < <endl;
cout < <c.C::doGetData() < <endl;

system( "PAUSE ");

return   0;
}

///////////////////////////////////////////////////////
运行的结果是
1
1
1
1
1
0
1
1
不明所以……

[解决办法]
眼花……

Class C 完全就是障眼的,关键在于 Class B 和 Class A 以及 Class A 内的 virtual int doGetData(); 和 Class B 的 int doGetData() { return m_data; };
[解决办法]
#include <iostream>
using namespace std;

class A
{
protected:
int m_data; // A::m_data
public:
A(int data = 0){m_data = data; } // A::m_data = data (0)
int GetData(){return doGetData();}
virtual int doGetData(){ return m_data;} // A::m_data
};

class B:public A
{
protected:
int m_data; // B::m_data, 与A::m_data是两个不同的量
public:
B(int data = 1){m_data = data; } // B::m_data data (1)

int doGetData(){ return m_data;} // B::m_data
};

class C:public B
{
protected:
int m_data; // C::m_data, 与A::m_data, B::m_data都不同
public:
C(int data = 2){m_data = data; } // C::m_data = data (2)


};


int main()
{
C c(10); // C::m_data = 10;
// C::B::m_data = 1 (通过B(data=1)得到的默认值)
// C::B::A::m_data = 0 (通过A(data=0)得到的默认值)

cout < <c.GetData() < <endl; //==> B::GetData()==> B::doGetData,
// 返回 B::m_data = 1;
cout < <c.A::GetData() < <endl; //==> A::GetData()==> B::doGetData
//(因为doGetData()是虚函数),
// 返回 B::m_data = 1
cout < <c.B::GetData() < <endl; //==> B::GetData==> B::doGetData, 结果同上 1
cout < <c.C::GetData() < <endl; //==> B::GetData==> B::doGetData, 结果同上
cout < <c.doGetData() < <endl; //==> B::doGetData, 结果同上

cout < <c.A::doGetData() < <endl; // 直接调用A::doGetData,
// doGetData的虚函数特性不起作用,
//返回A::m_data = 0

cout < <c.B::doGetData() < <endl; // 直接调用B::doGetData, 返回B::m_data = 1
cout < <c.C::doGetData() < <endl; // 直接调用B::doGetData
// (因为C没有override doGetData), 结果同上

system( "PAUSE ");

return 0;
}

[解决办法]
cout < <c.GetData() < <endl; // 调用B的doGetData, 返回的是C中B对象的data 1
cout < <c.A::GetData() < <endl; // 同上
cout < <c.B::GetData() < <endl; // 同上
cout < <c.C::GetData() < <endl; // 同上
cout < <c.doGetData() < <endl; // 同上
cout < <c.A::doGetData() < <endl; // 调用A的doGetData, 返回的是C中A对象的data 0
cout < <c.B::doGetData() < <endl; // 同上上
cout < <c.C::doGetData() < <endl; // 同上

原因是在构造C对象时调用B, A的构造函数.
而A的函数GetData调用自己的虚函数do, B重载了A的虚函数.

C的对象结构由两部分组成:
C::m_data和B类型对象.
B的对象结构由两部分组成:
B::m_data和A类型对象.
A的对象结构由三部分组成:
A::m_data, vptr, vtable

C::m_data = 10.
B::m_data = 1.
A::m_data = 0.
vtable中doGetData指针指向B::doGetData.

所以除了调用A::doGetData, 都会返回B::m_data.
[解决办法]
等我有空给你画张图吧,比较直接……
[解决办法]
C的GetData()是从B里继承来的吧
[解决办法]
多层的虚继承调用的时候,应该是调用离派生类最近的继承类的函数吧 ~~?

热点排行