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