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

一道笔试题关于虚函数调用

2013-09-05 
求助一道笔试题关于虚函数调用代码如下#include iostreamusing std::coutusing std::endlclass A{prot

求助 一道笔试题关于虚函数调用
代码如下

#include <iostream>

using std::cout;
using std::endl;

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(void)
{
C c(10);

cout << c.GetData() << endl;
cout << c.doGetData() << endl;
system("PAUSE");
return 0;
}


求它的输出结果(答案是1和1)
问题是:GetData()中调用doGetDdata()的时候为什么调用的是B中的doGetData()?
这个不是动态调用吧?
是怎么查找到B中doGetData这个名字的??

求指教~ C++ virtual
[解决办法]
 1.c.GetData()---- GetData()函数c中没有,怎么办?查继承表,直接继承的B中也没有,再继续查,A中找到,但是是虚函数,所以原路返回,在距离C类最近的地方找到,那就是B类的了,退一万步讲,也不该是A类行的 GetData() 为啥?因为现实生活中,你和你父亲也许还长得有那么几分相似,但和你爷爷的爷爷会更相似吗?所以,B是最佳选择,   
2.c.doGetData()----doGetData()中也没有,沿着继承链向上找,B中就有,而且个要求都不错,就直接给你用了。很明显,B留给C的遗产,如楼上所说,即便是A留给B的遗产,可那都属于B的东西了
[解决办法]
引用:
代码如下
#include <iostream>

using std::cout;
using std::endl;

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(void)
{
C c(10);

cout << c.GetData() << endl;
cout << c.doGetData() << endl;
system("PAUSE");
return 0;
}



求它的输出结果(答案是1和1)
问题是:GetData()中调用doGetDdata()的时候为什么调用的是B中的doGetData()?
这个不是动态调用吧?
是怎么查找到B中doGetData这个名字的??

求指教~

doGetDdata的调用不用怀疑的确属于多态,你过去所学的关于多态的知识并不完整,或者说只教会你表面的皮毛,甚至是错误的东西。

虚函数的调用是通过动态类型识别进行的,而调用哪一个虚函数是由最终覆盖者(final overrider)决定的。对于虚函数,其实无论通过对象还是指针或者引用进行调用,都启用了多态机制,只不过通过对象调用时,由于静态类型与动态类型必定相同,因此表面看来没有表现出多态的特性而已。哪种关于对象没有多态的说法其实是误解,它不是没有多态,只不过没有表现出来而已。

对于你的例子,调用c.GetData()时,由于c继承的GetData不是虚函数,所以按静态类型调用从C继承而来的GetData,但在GetData内部调用doGetDdata时,GetData首先解析到的doGetDdata是A内部的doGetDdata,而且是virtual,此时动态类型识别机制启动,就是说,编译器马上开始解析调用doGetDdata的动态对象是哪一个,明显是一个C对象,于是进入下一步决定C对象的final overrider,由于C不存在doGetDdata,此时C的final overrider就是B的doGetDdata了,所以才输出1。
[解决办法]
构造、析构中调用的虚函数;或者加了类型作前缀(c.A::doGetData())才不会产生多态

热点排行