1. 程式人生 > >C++覆蓋(虛擬函式的實現原理)

C++覆蓋(虛擬函式的實現原理)

Class Shape
{
public:
    virtual void cal_area()
    {
    }
private:
    int m_ir;
};

Class Circle:public Shape
{
public:
    virtual void cal_area()
    {
    }
};

類Circle繼承類Shape

當用Shape類例項化一個指標物件,並

Shape *shape=new Circle;

此時的虛擬函式是如何實現的呢?
當例項化一個Shape物件時,除了生成資料成員,還會生成一個虛擬函式表指標成員,這個虛擬函式表指標與虛擬函式表同時出現,虛擬函式表只有一個,而虛擬函式表指標指向虛擬函式表的首地址,在虛擬函式表中定義了一個函式指標,這個函式指標指向了計算面積函式的首地址,當在主函式中呼叫了計算面積的函式時,編譯器通過虛擬函式表指標找到虛擬函式表,再在虛擬函式表中找到指向計算面積函式的指標,通過這個指標找到函式的入口地址,從而呼叫虛擬函式。
這裡寫圖片描述

當派生類Circle中沒有同名的計算面積函式時,在例項化Circle的時候也會生成虛擬函式表指標和一個虛擬函式表,而虛擬函式表中也有一個指向計算面積函式的指標,這個指標是從它的基類中繼承來的,所以當在主函式中呼叫計算面積函式時,可以呼叫基類中所定義的計算面積函式。

當派生類Circle中定義了同名的計算面積函式時(無論它前面有沒有virtual修飾,只要基類中的同名函式被virtual修飾,那麼編譯器會自動給派生類中的同名函式加上virtual字首),例項化Circle的時候也會生成虛擬函式表指標和一個虛擬函式表,而虛擬函式表中也有一個指向計算面積函式的指標,這個指標一開始的值是從基類繼承而來,但在例項化Circle之後,這個值就會被Circle類中定義的計算面積函式的首地址所覆蓋。
這裡寫圖片描述

這就是C++中的覆蓋的定義,要與隱藏區分開來。