下面程序的运行结果是:
A::Fun
C::Do
请填空。
#include <iostream>
using namespace std;
class A {
private:
int nVal;
public:
void Fun(){ cout << "A::Fun"<<endl;}
void Do(){ cout << "A::Do"<<endl;}
};
class B:public A{
public:
virtual void Do(){ cout << "B::Do"<<endl;}
};
class C:public B {
public:
void Do(){ cout << "C::Do"<<endl;}
void Fun() { cout << "C::Fun"<<endl;}
};
void Call(**2分** ){
p.Fun();
p.Do();
}
int main(){
C c;
**2 分**
;
return 0;
}
为什么这么填,程序是怎么运行的?
题目没有出错,这个是在考察 引用切割的问题,答案:
void Call(B & p); //1
Call(c); //2
传递引用不会造成对象实现被切割,虚函数指针指向无误 即 C::Do,但是造成父类函数覆盖子类函数。即 A::Fun。
前一个回答应该认为在考察动态多态和虚函数的问题,动态多态的调用是 基类指针指向子类对象,这里 Call 里边的常理实现应该是使用指针
void Call(A * p)
{
p->Fun();
p->Do();
}
int main()
{
C c;
Call(&c);
}
因为在 B中 Do 函数被声明为 virtual 所以 C 中即便没有写关键字 virtual 也为虚函数,基类指针指向子类对象,就会调用 子类的实现,即 C::Do
而 Fun 函数一直都不为虚函数,则会一直调用指针对应的函数。即 A::Fun
题目应该是出错了。
无非就是Ap Bp Cp以及Call(c); call((B)c); call((A)c); 9种排列组合,但是都不行。