Edmund's zone

导航

绝不重新定义继承来的非虚函数

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的关系。

posted on 2015-04-24 11:21  Edmund Li  阅读(195)  评论(0编辑  收藏  举报