毫不從新定義繼承來的非虛函數

class B
{
    public:
        void mf();
        ...
};

class D: public B {...};

對於以下行爲:ide

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指向一個類型爲派生類的對象。spa

虛函數是動態綁定(dynamically bound)的,若是mf是個虛函數,不論經過pB或是pD調用mf,都會調用D::mf,由於pB和pD真正指的都是一個類型爲D的對象。code

解決:若是D真的想要出現與B不同的mf,那就把mf聲明爲virtual吧。對象

牢記:public繼承意味着父類子類是一種is-a的關係。blog

相關文章
相關標籤/搜索