一道笔试题关于虚函数调用
求助一道笔试题关于虚函数调用代码如下#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())才不会产生多态