虛函式的一些想像

2021-06-19 09:57:50 字數 848 閱讀 3355

看了vc中虛函式的實現原理,突然覺得很有意思,就寫了如下的**:

答案是:

classb:d=11,c=99

classa.showb:b=11

classa.showa:a=99

可能有些奇怪,但是想清楚了就覺得很自然了。首先classa和classb都擁有虛函式,對於這樣的類就會有乙個公共的虛函式表,採用單件模式(singleton)所有類的物件共享這乙個虛函式表,每個類的物件所在記憶體的前四個位元組儲存的是虛函式表的首位址。

下面看看classa在記憶體中的結構:

[虛函式表位址]  [變數a]  [變數b]

4位元組        4位元組     4位元組

再看看classb在記憶體中的結構:

[虛函式表位址]  [變數c]  [變數d]

4位元組        4位元組     4位元組

所以可見當我們將classa的物件a強制型別轉換為classb的時候。由於虛函式表(儲存函式位址的陣列)中具體函式位址的偏移是按照函式據在**中定義的順序,所以當執行pb->showa()對於classb而言是執行虛函式表中第二個函式。由於classb的物件指標pb是由classa的物件強制型別轉換過來的,所以現在虛函式表並不是classb的函式表而是classa的。所以執行虛函式表中第二個函式也就是執行classa中虛函式的第二個。也就是classa::showb()。同樣道理可以解釋為什麼pb->showb()的執行結果。對於pb->show()。由於show()不是虛函式,所以在編譯階段就已經確定了執行函式,執行的仍然是classb中的show()。變數也按照先後順序對應起來。強制型別轉換後類classa的物件a中的變數a就對應著classb中的c。b則就是對應於d。所以有上面的輸出結果。

虛函式的一些總結

虛函式與虛函式表 1 每個類只有乙個虛函式表 如 cout int int bb1 其中對於 cout int int bb1 bb1是取得物件的首位址,因為含有虛函式的物件中的首位址儲存的是虛指標的位址,所以 bb1就是虛指標的位址 int bb1是將虛函式的位址解釋為int型別 int bb1 ...

虛函式,純虛函式,多型的一些理解

定義乙個函式為虛函式,不代表函式為不被實現的函式。定義他為虛函式是為了允許用基類的指標來呼叫子類的這個函式。定義乙個函式為純虛函式,才代表函式沒有被實現。定義他是為了實現乙個介面,起到乙個規範的作用,規範繼承這個。類的程式設計師必須實現這個函式。1 為了方便使用多型特性,我們常常需要在基類中定義虛函...

關於c 的虛函式的一些總結

對於什麼時候子類會覆蓋父類中的函式 1 如果子類的東西和父類是一樣的,那麼肯定是子類覆蓋父類中的函式 2 如果子類的函式和父類的函式一模一樣,就是前面少了個virtual那麼,子類還是覆蓋父類的函式 3 如果子類和父類的函式返回值不一樣,那麼子類是不覆蓋父類的函式 4 最糾結的應該算是對於引數含有預...