1. 程式人生 > >C++ 虛擬函式表研究 (二) 多重繼承

C++ 虛擬函式表研究 (二) 多重繼承

                                     C++  虛擬函式表研究 (二)  多重繼承

        上次研究的是單繼承的情況,這次研究多重繼承下的虛擬函式表的排列情況。

         這次A,A1,A2,B這幾個類的繼承關係如下圖:

        

              各個類的宣告如下:

             

              測試程式碼如下:

             

              測試程式碼說明:

     A1,A2的虛擬函式表都是單繼承自A,所以跟上一篇的單繼承的情況完全相同,這裡不再解釋。

              具體說下B的情況,b分別從A1,A2繼承了兩個虛擬函式表,這兩個虛擬函式表也是在物件的開始按照順序開始排列,先是A1的虛擬函式表,然後是A2的虛擬函式表。

              B的第一個虛擬函式表:(int *)(&b)

              B的第一個虛擬函式表的第一個元素fun1=  * ((int *)  * (int *)(&b))

              B的第一個虛擬函式表的第二個元素fun2=  * ((int *)  * (int *)(&b)+1)

              ......

              B的第二個虛擬函式表:(int *)(&b)+1

              B的第二個虛擬函式表的第一個元素 fun1=   *    

              B的第二個虛擬函式表的第二個元素 fun2=  * ((int *) *((int *)(&b)+1)+1)

              ......

             程式執行結果:

A1虛擬函式表的地址為:0012FF7C
A1第一個虛擬函式的地址為:0047012C
A1::fun1
A::fun2
A::fun3
A2虛擬函式表的地址為:0012FF68
A2第一個虛擬函式的地址為:00470160
A::fun1
A2::fun2
A2::fun3
B的第一個虛擬函式表的地址為:0012FF60
B的第一個虛擬函式表的第一個虛擬函式的地址為:004701A4
A1::fun1
A::fun2
A::fun3
B::fun4
B的第二個虛擬函式表的地址為:0012FF64
B的第二個虛擬函式表的第一個虛擬函式的地址為:00470194
A::fun1
A2::fun2
A2::fun3

     結果畫成虛擬函式表如下:

     A的虛擬函式表圖:

     

     A1的虛擬函式表圖:

    

     A2的虛擬函式表圖:

    

    B的虛擬函式表圖:

      

     結論:

     多重繼承會有多個虛擬函式表,幾重繼承,就會有幾個虛擬函式表。這些表按照派生的順序依次排列,如果子類改寫了父類的虛擬函式,那麼就會用子類自己的虛擬函式覆蓋虛擬函式表的相應的位置,如果子類有新的虛擬函式,那麼就新增到第一個虛擬函式表的末尾。