class B { public: void mf(); ... }; class D: public B {...};
对于如下行为:
D x; B *pB = &x; pB->mf(); //和如下的代码 D *pD = &x; pD->mf();
如上调用的两个mf()理应是相同的,但是如果mf()是个虚函数而且D有自己的mf版本,那就有问题了:
class D: public B { public: void mf();//hides B:mf(); ... }; pB->mf(); //B::mf() pD->mf(); //D::mf()
上面两种情况出现的原因是,非虚函数B::mf和D::mf都是静态绑定(statically bound)的,也就是说,由于pB被声明为pointer-to-B,通过pB调用的非虚函数永远是B所定义的版本,即使pB指向一个类型为派生类的对象。
虚函数是动态绑定(dynamically bound)的,如果mf是个虚函数,不论通过pB或是pD调用mf,都会调用D::mf,因为pB和pD真正指的都是一个类型为D的对象。
解决:如果D真的想要出现与B不一样的mf,那就把mf声明为virtual吧。
牢记:public继承意味着父类子类是一种is-a的关系。