1. 程式人生 > >虛函數相關問題分析

虛函數相關問題分析

註意 默認 -s 函數 ack family font 以及 處理

 1、靜態聯編和動態聯編
將源碼中的函數調用解釋為執行特定的函數代碼塊被稱為函數名聯編。

在C語言中。這很easy,由於每一個函數名都相應於一個不同的函數。

在C++中,由於函數重載的緣故。這項任務更復雜。編譯器必須查看函數參數以及函數名才幹確定使用哪個函數。然而,C/C++編譯器可以在編譯過程中完畢這樣的聯編。

在編譯過程中進行聯編稱為靜態聯編。又稱為早期聯編。只是虛函數使這項工作變得更困難。

由於編譯器不知道將選擇哪種類型的對象。所以,編譯器必須生成可以在程序執行時選擇正確的虛方法的代碼。這被稱為動態聯編,又稱為晚期聯編。

2、指針和引用類型兼容性
通常,C++不同意將一種類型的地址賦給還有一種類型的指針,也不同意一種類型的引用指向還有一種類型:
double x = 2.5;
int* pi = &x;//invalid assignment
long& r1 = x;//invalid assignment
只是,正如我們看到的。指向基類的引用或指針能夠引用派生類對象,而不必進行顯示類型轉換。
將派生類引用或指針轉換為基類引用或指針被稱為向上強制轉換,這使公有繼承不須要進行顯示類型轉換。該規則是is-a關系的一部分。向上強制轉換時可傳遞的,也就是說,假設A派生出B,B派生出C,則A指針或引用能夠引用A對象、B對象或C對象。
相反的過程---將基類指針或引用轉換為派生類指針或引用---稱為向下強制轉換,假設不使用顯示類型轉換。則向下強制轉換時不同意的。


3、編譯器對非虛方法使用靜態聯編,對虛方法使用動態聯編。C++編譯器默認使用靜態聯編。


4、虛函數的工作原理
通常,編譯器處理虛函數的方法是:給每一個對象加入一個隱藏成員。隱藏成員中保存了一個指向函數地址數組的指針。

這樣的數組稱為虛函數表。

虛函數表中存儲了為類對象進行生明的虛函數的地址。比如,基類對象包括一個指針。該指針指向基類中全部虛函數的地址表。派生類對象將包括一個指向獨立地址表的指針。假設派生類提供了虛函數的新定義,該虛函數表將保存新函數的地址;假設派生類沒有又一次定義虛函數,該虛函數表將保存函數原始版本號的地址。假設派生類定義了新的虛函數。則該函數的地址也將被加入到虛函數表中。


5、註意事項
假設在派生類中又一次定義函數。將不是使用同樣的函數特征標覆蓋基類聲明。而是隱藏同名的基類方法,無論參數特征標怎樣。這將引出兩條經驗規則:
①假設又一次定義繼承的方法,應確保與原來的原型全然同樣,但假設返回類型是基類引用或指針,則能夠改動為指向派生類的引用或指針。這樣的特性被稱為返回類型協變,由於同意返回類型隨類類型的變化而變化。
②假設基類聲明被重載了,則應在派生類中又一次定義全部的基類版本號。

假設僅僅又一次定義一個版本號。則另外兩個版本號將被隱藏。派生類對象將無法使用它們。

虛函數相關問題分析