虛函數

定不定義

普通成員函數只要沒用到可以不寫定義,但虛函數只要在主函數被用到,所有父類和子類必須都定義該函數,因爲編譯器只有在運行時才能確定用到哪個函數

調用虛函數

指針或引用運行時解析

有兩種類型:動態和靜態。

這裏有動態類型和靜態類型,只有在運行時才知道動態類型。

Quote base;
print_total(cout, base, 10);  //調用Quote::net_price()

Bulk_quote derived;
print_total(cout, derived, 10);  //調用Bulk_quote::net_price()

普通類型編譯時解析

只有一種類型:只有靜態了。

如果我們通過普通類型調用虛函數,就只會調用靜態類型的函數。

base = derived;   //動態和靜態類型一致
base.net_price(20); //調用Quote::net_price

 調用普通函數

測試都是調用基類的函數。

虛函數重寫叫覆蓋,普通函數重寫叫隱藏。

class Base
{
public:
    void f()
    {
        cout<<"Base"<<endl;
    }
};

class Derived: public Base
{
public:
    void f()   //報隱藏非虛函數
    {
        cout<<"Derived_f"<<endl;
    }

    void g()
    {
        cout<<"Derived_g"<<endl;
    }
};



int main() {

    Base base;
    Derived derived;

    Base *p = &base;
    p ->f();    //輸出Base
    p ->g();   //xxx ,報class Base無此函數
 
    p = &derived;
    p ->f();  //輸出Base
    p ->g();   //xxx ,報class Base無此函數

    return 0;

}

口訣-Primer537

普通函數普通類型靜態時,虛函數指針或引用運行時,普通類型還是靜態時。

只有虛函數和引用或指針這倆條件都滿足,纔會動態綁定。

關鍵字

virtual關鍵字的範圍

只要聲明爲virtual,派生類就不用聲明瞭。

虛函數叫覆蓋,形參和返回值都要完全匹配。

override關鍵字

動機

有時我們寫了相同名字的函數,但形參列表和想覆蓋的虛函數不同,這時編譯器視爲新函數,但是其實是想覆蓋,這是一個不小心的錯誤。可以加上override來幫助檢查。

final關鍵字

既可以不讓類繼承,也可以不讓函數覆蓋

忽略虛函數機制

加上作用域就行。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章