天天看點

C++多态2 虛函數表一、虛函數表

一、虛函數表

父類Shape                                                                                   子類Circle

C++多态2 虛函數表一、虛函數表
C++多态2 虛函數表一、虛函數表

父類 Shape

C++多态2 虛函數表一、虛函數表

vftable_ptr是一個虛表指針,它指向一個存放該類對象的所有虛函數的位址的表;虛函數表與Shape類的定義同時出現,虛函數表占有一定的空間;假設虛函數表的起始位置為0xCCFF,那麼虛表指針的值就是0xCCFF;父類的虛函數表隻有一個,通過父類執行個體化出來的所有對象,他的虛表指針的值都是0xCCFF,以確定他的每一個對象的虛表指針指向自己的虛函數表。

調用的時候找到虛表指針,再通過虛表指針找到虛函數表,再通過位置的偏移找到相應的入口位址,進而找到calcArea()

虛表是一個指針數組,其元素是虛函數的指針,每個元素對應一個虛函數的函數指針。

虛表内的條目,即虛函數指針的指派發生在編譯器的編譯階段,也就是說在代碼的編譯階段,虛表就可以構造出來了。

子類Circle

C++多态2 虛函數表一、虛函數表

circle沒有虛函數,但是他繼承了shape類,circle類擁有自己的虛函數表,通過他調用的calcArea()函數是父類的該函數

如果将Circle類改為

C++多态2 虛函數表一、虛函數表

那麼Circle

C++多态2 虛函數表一、虛函數表

執行的是子類的calcArea()

虛析構函數:

前提:執行完子類的析構函數就會執行父類的析構函數

當父類的指針指向子類的對象時,使用父類的指針,通過delete的方式去釋放子類的對象,隻要能夠要實作通過父類的指針執行到子類的析構函數

二、什麼時候會執行函數的動态綁定?這需要符合以下三個條件

(1)通過指針來調用函數

(2)指針upcast向上轉型(繼承類向基類的轉換稱為upcast)

(3)調用的是虛函數

如果一個函數調用符合以上三個條件,編譯器就會把該函數調用編譯成動态綁定,其函數的調用過程走的是上述通過虛表的機制。

三、在多态的情況下,虛函數表指針在對象當中所占據的記憶體位置是每個對象的前四個基本記憶體單元,後面依次排列的是其他資料成員

其他:c++對于一個資料成員都沒有的情況,為了标明它的存在,用一個記憶體單元去标記他

繼續閱讀