程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 虛方法的調用是怎麼實現的(單繼承VS多繼承)

虛方法的調用是怎麼實現的(單繼承VS多繼承)

編輯:C++入門知識

我們知道通過一個指向之類的父類指針可以調用子類的虛方法,因為子類的方法會覆蓋父類同樣的方法,通過這個指針可以找到對象實例的地址,通過實例的地址可以找到指向對應方法表的指針,而通過這個方法的名字就可以確定這個方法在方法表中的位置,直接調用就行,在多繼承的時候,一個類可能有多個方法表,也就有多個指向這些方法表的指針,一個類有多個父類,怎麼通過其中一個父類的指針調用之類的虛方法?

其實前面幾句話並沒有真正說清楚,在單繼承中,父類是怎麼調用子類的虛方法的,還有多繼承又是怎麼實現這點的,想知道這些,請認真往下看。

我們先看單繼承是怎麼實現的。先上兩個簡單的類:

#include <iostream> 
  ~ <<<< SetA(= B: ~ <<<< <<<< (*Fun)(<<<<** pVtab0 = (**)& ( i=; (Fun)pVtab0[][i]!=NULL; i++= (Fun)pVtab0[<< <<i<<<<* b1=&<<<<** pVtab1 = (**)& ( i=; (Fun)pVtab1[][i]!=NULL; i++= (Fun)pVtab1[<< <<i<<<<<<<<** pVtab2 = (**)&* ( i=; (Fun)pVtab2[][i]!=NULL; i++= (Fun)pVtab2[<< <<i<<<<<<<<&b<<<<<<b1<<endl<<

運行結果如下:

通過運行結果我們知道:通過父類指向子類的指針調用的是子類的虛方法。在單一繼承中,雖然父類有父類的虛方法表,子類有子類的虛方法表,但是子類並沒有指向父類虛方法的指針,在子類的實例中,子類和父類是公用一個虛方法表,當然只有一個指向方法表的指針,為什麼可以公用一個虛方法表呢,虛方法表的第一個方法是析構函數,子類的方法會覆蓋父類的同樣的方法,子類新增的虛方法放在虛方法表的後面,也就是說子類的虛方法表完全覆蓋父類的虛方法表,即子類的每個虛方法與父類對應的虛方法,在各種的方法表中的索引是一樣的。

但是在多繼承中就不是這樣了,第一個被繼承的類使用起來跟單繼承是完全一樣的,但是後面被繼承的類就不是這樣了,且仔細往下看。

還是先上3個簡單的類

#include <iostream> 
  ~ <<<< ~ <<<< <<<< C: A, ~  GetB()
<<<< <<<< <<<< (*Fun)(* c=* a=* b=<<<<(C)<<endl<<<<<<c<<<<<<a<<<<<<b<<endl<<endl<<<<<<** pVtab1 = (**)&* ( i=; (Fun)pVtab1[][i]!=NULL; i++= (Fun)pVtab1[<< <<i<<<<&*pFun<<    <<endl<<<<<<= (**)&* ( i=; (Fun)pVtab1[][i]!=NULL; i++= (Fun)pVtab1[<< <<i<<<<&*pFun<<    

運行結果如下:

從結果說話:

Sizeof(C)=20,我們並不意外,在單繼承的時候,父類和子類是公用一個指向虛方法表的指針,在多繼承中,同樣第一個父類和子類公用這個指針,而從第二個父類開始就有自己單獨的指針,其實就是父類的實例在子類的內存中保持完整的結構,也就是說在多重繼承中,之類的實例就是每一個父類的實例拼接而成的,當然可能因為繼承的復雜性,會加一些輔助的指針。

指針a與指針c指向同一個地址,即c的首地址,而b所指的地址與a所指的地址相差8字節剛好就是類A實例的大小,也就是說在C的內存布局中,先存放了A的實例,在存放B的實例,sizeof(B)=8(字段int b和指向B虛方法表的指針),在家上C自己的字段int c剛好是20字節。

讓我有點意外的是:方法B::SB,C::GetB並沒有出現在類C的方法表中,而且C::GetB是C覆寫B中的GetB方法,怎麼沒有出現在C的方法表中呢?在《深入探索C++對象模型》一書中講到,這兩個方法同時應該出現在C的方法表中,同樣也會覆蓋B的虛方法表。可能是不通的編譯器有不同的實現,我用的是VS2010,那本書上講的是編譯器cfront

OK,我們不用管不同的編譯器實現上的區別,這點小區別無傷大雅,虛方法的調用機制還是一樣的。

先來分析幾個小例子,看看虛方法的實現機制。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved