关于#c++#的问题:下面程序的运行结果是:A::FunC::Do请填空

下面程序的运行结果是:
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种排列组合,但是都不行。