多態是一種運行期綁定機制,通過這種機制,實現將函數名綁定到函數具體實現代碼的目的。 一個函數在記憶體當中起始的地址就稱為這個函數的入口地址。
多態就是將函數名稱動態地綁定到函數入口地址的運行期綁定機制。
C++中的運行期綁定與編譯期綁定
一個函數的名稱與其入口地址是緊密相連的,入口地址是函數在記憶體當中的起始地址。
#include <iostream>
usingnamespace std;
void sayHi();
int main() {
sayHi();
return 0;
}
void sayHi() {
cout<<“Hello,wonderful world!”<<endl;
}
編譯期綁定是函數需要執行的代碼由編譯器在編譯階段確定了的。也就是說將某個函數名和其入口地址進行綁定在一起。
運行期綁定是直到程式運行之時(不是在編譯時間刻),才將函數名稱綁定到其入口地址。
如果對一個函數的綁定發生在運行時刻而非編譯時間刻,我們就稱該函數是多態的。
注意的幾點:
ü 基類中被聲明了為虛函數的成員函數,在被繼承以後的衍生類別當中即使不被顯式的聲明為虛函數,它也自動地被認為是虛函數。ü 虛函數在類聲明之外定義,關鍵字virtual僅在函式宣告是需要,不需在函數定義中使用virtual關鍵字。ü C++僅允許將成員函數定義為虛函數,頂層函數不能為虛函數
虛成員函數繼承
和普通成員函數一樣,在衍生類別中虛成員函數也可以從基類繼承。
運行期綁定和虛成員函數表
C++是使用vtable(虛成員函數表)來實現虛成員函數的運行期綁定。
使用動態綁定的程式會影響效率,因為虛成員函數需要額外的儲存空間,而且對虛成員函數表進行查詢也需要額外的時間。
重載
重載函數和虛函數的區別在於前者是編譯期綁定的,後者是運行期綁定
抽象基類和純虛成員函數
抽象基類不能被執行個體化,其可以用來指明某些必須被衍生類別覆蓋的虛函數,這樣就可以讓一些類具有共同的介面,它們都是繼承於某個抽象基類的。
class Abstract
{
pulbic:
virtual void open() = 0;
};
定義純虛成員函數的限制
只有虛函數才可以成為純虛成員函數,非虛函數或頂層函數都不能聲明為純虛成員函數。