虛函式及虛函式表

2021-08-07 23:43:07 字數 2953 閱讀 8443

虛函式及虛函式表

首先,我們要分清三大概念:過載、重寫(覆蓋)和重定義

一. 函式過載

(1)在相同的作用域內(無繼承關係,只在乙個類內進行宣告)

(2)進行多個函式宣告

(3)多個函式的函式名相同,引數列表不同(可以是型別不同、引數型別不同、傳參順序不同)

(4)函式的返回值型別可以相同,可以不同。不能僅依靠函式返回值型別來判斷該函式是否為過載。

二. 重寫(覆蓋)

(1)在不同的作用域內進行函式宣告(存在於繼承關係下,分別在基類和派生類中進行宣告)

(2)能發生重寫的函式被定義成虛函式

(3)重寫發生在繼承關係中,必須將基類函式前加上virtual關鍵字,將其宣告為虛函式。派生類函式可加可不加。

(4)基類和派生類中發生重寫的函式必須一模一樣(函式返回值型別、函式名、引數列表中的引數型別、引數名、傳參

順序都必須相同)。

三. 重定義(隱藏)

(1)在不同的作用域內進行函式宣告(存在於繼承關係下,分別在基類和派生類中進行宣告)

(2)函式名相同

(3)函式返回值型別可以相同可以不同

(4)在繼承關係中,同名函式只要不構成重寫,那就構成重定義(隱藏)

引數列表相同時,基類函式有virtual,構成重寫;無virtual,構成重定義。

引數列表不同時,無論基類函式有無virtual,構成的都是重定義(隱藏)。

**多型

多型可以簡單地理解成「乙個介面,多種方法」的實現。利用c++的多型性,使得程式在執行時才確定呼叫的函式,實現

了介面重用。也就是說,無論傳遞過來的是哪乙個類的物件,函式都可以通過同乙個介面呼叫到適用於不同物件的函式。

在c++中,多型性是依靠虛函式來實現的。在繼承關係中,將基類函式定義為虛函式,在子類中宣告和基類虛函式完全

相同的函式,此時,發生函式的重寫。在虛函式表中修改函式的位址,實現「乙個介面,多種方法」。

最常用的使用方法就是宣告乙個基類物件的指標,並使其指向乙個子類物件的位址,通過虛函式的多型性呼叫子類物件

的函式,可以根據子類物件的不同而實現不同方法的呼叫。如果不使用虛函式,基類指標指向子類物件時只能呼叫子類物件

繼承基類而得的資料,而不能訪問到子類物件中新增的成員。

總結:多型的使用通過虛函式的重寫實現。將繼承關係下的基類函式成員宣告為虛函式,子類中與基類虛函式相同的函式會在

子類的虛函式表中重寫(覆蓋)基類函式的位址。通過常用方法(將基類物件指標指向子類物件),實現多型下的「乙個介面,

多個方法「。

多型性通過虛函式實現,虛函式存在於繼承關係下,下面,我們分別分析單繼承和多繼承下的多型使用

單繼承

#include#includeusing namespace std;

class person

virtual void fun2() };

class student:public person

virtual void fun3()

{}};

int main()

執行結果:

結構示意圖:

分析執行結果:

在單繼承中,student類繼承了person類,student類中宣告fun1為虛函式,在派生類中存在與fun1相同的函式,構成重寫。

重寫時,把基類的虛函式表的虛函式person::fun1()位址改寫成子類虛函式student::fun1()的位址。

若未使用到c++的多型性,直接用基類物件呼叫函式時,呼叫的是未被重寫的虛函式表,從中找到要呼叫的函式的位址;

若使用到c++的多型性,將基類物件指標指向子類物件的位址,此時呼叫函式時,是從被重寫後的虛函式表中進行查詢,從而

呼叫到相應的函式。

注意:基類指標只能訪問到派生類中繼承基類的資料,所以出現重寫,重寫積累的虛函式表,使得指向派生類的基類的物件指標

能夠訪問到派生類中的新增成員。

單繼承情況下,只有乙個虛函式表,子類符合重寫條件的函式在基類的虛函式表中進行重寫,構成新的虛函式表。

多繼承

#includeusing namespace std;

#includeclass base1

virtual void fun2() };

class base2

virtual void fun4() };

class derived :public base1, public base2

void fun3()

virtual void fun5() };

int main()

執行結果:

結構示意圖:

分析執行結果:

在多繼承中,子類derived繼承了基類base1和基類base2。在使用多型之前,基類base1、base2都有其各自的虛函式表,

表內分別存放著各自虛函式的位址。在派生類多繼承基類之後,派生類中存在與基類虛函式構成重寫的虛函式,於是基類的虛

函式表發生了變化,用派生類中符合重寫條件的虛函式的位址覆蓋掉對應的基類虛函式的位址。

值的注意的是,派生類中新增的虛函式的位址存放在base1的虛函式表中。我們可以記住這個結論,即派生類的新增的虛

函式位址存放在它第乙個繼承的基類的虛函式表中。

虛函式表指標,虛函式表

對c 了解的人都應該知道虛函式 virtual function 是通過一張虛函式表 virtual table 來實現的。簡稱為v table。在這個表中,主是要乙個類的虛函式的位址表,這張表解決了繼承 覆蓋的問題,保證其容真實反應實際的函式。這樣,在有虛函式的類的例項中這個表被分配在了 這個例項...

C 虛函式及虛函式表詳解

多型 的關鍵在於通過基類指標或引用呼叫乙個虛函式時,編譯時不確定到底呼叫的是基類還是派生類的函式,執行時才確定。include using namespace std class a virtual void func2 class b public a int main 在 32 位編譯模式下,程...

虛指標,虛函式,虛函式表,純虛函式

虛指標 虛繼承 在使用多重繼承時,如存在 class a 有m a變數 class a1 virtual public a,m a1 class a2 virtual public a m a2 class b public a1,public a2 m b 時 存在以下記憶體儲存順序 虛指標 指向...