C 多型之虛表

2021-08-04 10:45:58 字數 3510 閱讀 2918

多型定義:多種形式或形態

多型分類

靜態多型:在編譯期間完成,編譯器根據函式實參的型別推斷出要呼叫哪個函式。

在這裡我們只說函式過載,泛型程式設計在後面再進行介紹。

函式過載的條件

(1)在同一作用域

(2)函式名相同,引數不同

(3)返回值可以不同

動態多型;在程式執行期間判斷所引用物件的實際型別,根據其實際型別呼叫相應的方法。

實現動態多型的條件

1.必須是虛函式

關於虛函式

使用virtual關鍵字修飾類的成員函式時,指明該函式為虛函式,派生類必須對其進行重寫。

將基類的某乙個成員函式定義為虛函式,在派生類中該函式始終保持虛函式的特

性。 只有類的非靜態成員函式才能定義為虛函式,靜態成員函式不能定義為虛函式。

重寫也稱覆蓋,函式重寫的條件

(1)不在同一作用域(分別在基類和派生類)

(2)函式原型相同(函式名相同,引數相同,返回值相同)

(3)基類函式必須有virtual關鍵字

(4)訪問修飾符可以不同

2.通過基類型別的引用或者指標呼叫虛函式

虛表:

對於有虛函式的類,編譯器都會維護一張虛表,物件的前4個位元組就是指向虛表的指標。

下面來看乙個派生類將基類的虛函式重寫的例子,分析一下基類和派生類各自的虛函式表

單繼承派生類的虛函式表生成

1.先拷貝基類的虛函式表生成;

2.如果派生類重寫了基類的某個虛函式,就用派生類重寫後的虛函式替換相同偏移量位置的虛函式;

3.如果派生類有新增的虛函式,跟在基類的虛函式位址後面。

class b1

virtual

void fun1()

virtual

void fun2()

private:

int _b1;

};class b2

virtual

void fun3()

virtual

void fun4()

private:

int _b2;

};class d :public b1, public b2

virtual

void fun1()

virtual

void fun3()

virtual

void fun5()

private:

int _d;

};typedef

void(*pvtf)();

void printvpt(b1& b1, const

char* _table)

cout

<< endl;

}void printvpt(b2& b2, const

char* _table)

cout

<< endl;

}void test()

int main()

多繼承多型派生類物件模型

多繼承派生類的虛函式表生成

多繼承派生類虛函式的順序

1.如果派生類對b1中虛函式重寫,替換相同位置的虛函式;

2.如果派生類對b2中虛函式重寫,替換相同位置的虛函式;

3.如果派生類有自己新增的函式,放在第一張虛表之後。

多型下的菱形虛擬繼承

class b

virtual

void fun1()

virtual

void fun2()

private:

int _b;

};class c1:virtual

public b

virtual

void fun1()

virtual

void fun3()

private:

int _c1;

};class c2 :virtual

public b

virtual

void fun4()

private:

int _c2;

};class d :public c1, public c2

virtual

void fun1()

virtual

void fun4()

virtual

void fun5()

private:

int _d;

};typedef void(*pvtf)();

void printvpt(void* p, const

char* _table)

cout << endl;

}void test()

int main()

菱形虛擬繼承派生類的物件模型

派生類的虛表生成

成員函式的呼叫過程

1.是否為虛函式

2.若為虛函式,找虛表指標->虛函式位址->呼叫相應的虛函式;若為非虛函式,直接呼叫相應的函式。

C 多型之虛函式

問題 用基型別的指標指向派生類物件時,通過這個指標來訪問該物件,這是會出現訪問到的只是從基類繼承來的同名成員。解決方法 在基類中將這個同名函式宣告為虛函式,這樣就可以通過基型別的指標,訪問不同派生類的物件產生不同的行為,從而實現執行過程的多型。語法 virtual 函式型別 函式名 形參表 注意 必...

C 之虛函式和多型

1.虛函式 簡單的說,虛函式就是在函式原型前加上virtual關鍵字。函式一旦被宣告為虛函式,即使類在改寫它的時候沒有將其宣告為虛函式,它從該點的繼承層次結構中仍然是虛函式。如果基類中乙個函式被宣告為虛函式,在若干子類中有著不同的實現,那麼我們在建立若干子類的不同物件時,可以用基類的指標或者引用來指...

C 多型實現之虛方法

控制台應用程式中,新建乙個people類檔案,如下 using system using system.collections.generic using system.linq using system.text namespace 13多型 public string name 1.第一,將父類...