//绝不重新定义继承而来的non-virtual函数
#include <iostream>
using namespace std;
class B{
public:
void mf()
{cout << "调用基类B成员函数" << endl;}
//......
};
class D:public B{
public:
void mf(){cout << "this is D running" << endl;}
//......
};
int main()
{
D x;
//***********************指针所展现的难以理解的行径***********************
cout << "指针情况下:"<< endl;
B *pb = &x;
D *pd = &x;
pb->mf();//pb虽然是指向派生类D的对象x,但是其所调用的函数却是 基类B
//(而非派生类D)的成员函数。输出结果为:“调用基类B成员函数”。
pd->mf();//其所调用的函数却是 派生类D 的成员函数。输出结果为:“this is D running”
x.mf(); //由于是D定义的对象,故调用 派生类D 的成员函数。输出结果为:“this is D running”
//*****************Reference也会展现和指针一样难以理解的行径*****************
cout << endl << "Reference情境:"<< endl;
B &rb = x;
D &rd = x;
rb.mf(); //输出结果为:“调用基类B成员函数”
rd.mf(); //输出结果为:“this is D running”
return 0;
}
原因是:
non-virtual函数如 B::mf 和 D::mf 都是静态绑定,通过pb调用的non-virtual函数永远是B所定义的版本,及时pb指向一个类型为“基类B的派生类的对象”。
但virtual函数却是动态绑定的,所以它们不受这个问题之苦,即 mf() 若为虚函数,不论pb还是pd,均是调用D::mf() ,因为它们真正指的为D类型的对象
(Reference亦此)。