C++多繼承多態的實現
如果一個類中存在虛函數,在聲明類的對象時,編譯器就會給該對象生成一個虛函數指針,該虛函數指針指向該類對應的虛函數表。
多態的實現是因為使用了一種動態綁定的機制,在編譯期間不確定調用函數的地址,在調用虛函數的時候,去查詢虛函數指針所指向的虛函數表。
派生類生成的對象中的虛函數指針指向的是派生類的虛函數表,因此無論是基類還是派生來調用,都是查詢的是派生類的表,調用的是派生類的函數。
如果發生了多繼承,多個基類中都有虛函數,那么該是怎樣的呢?虛函數指針如何排列,多個基類的指針為什么能夠同時指向派生類對象,同時發生多態?
請看下面這段程序
#include <stdio.h>#include <iostream>using namespace std;class Base1{ public: void fun() { printf("this is Base1 fun/n"); } virtual void fun1() { printf("this is Base1 fun1/n"); }};class Base2{ public: void fun() { printf("this is Base2 fun/n"); } virtual void fun2() { printf("this is Base2 fun1/n"); }};class Derived : public Base1,public Base2{ public: void fun() { printf("this is Derived fun/n"); } void fun1() { printf("this is Derived fun1/n"); } void fun2() { printf("this is Derived fun2/n"); }};int main(){ Derived *pd = new Derived(); Base1 *p1 = (Base1 *)pd; Base2 *p2 = (Base2 *)pd; p1->fun(); p2->fun(); p1->fun1(); p2->fun2(); printf("Base1 p1:%x/n", p1); printf("Base2 p2:%x/n", p2); return 0;}
運行結果如下
feng@mint ~/code/c++/cpp_muti_drived $ ./muti_derived this is Base1 funthis is Base2 funthis is Derived fun1this is Derived fun2Base1 p1:2097c20Base2 p2:2097c28
Derived類分別繼承了Base1和Base2,根據結果來看,均發生了多態。基類指針調用函數,調用的均是派生類的對象。
通過打印出了p1和p2的地址,發現他們相差了8個字節,就能明白了,在做類型轉換的過程中,如果把地址傳給第二個基類的指針的時候會自動把地址減去8,在64位系統下,剛好是一個指針的長度。因此p2指向的實際上是第二個虛函數指針的地址,這樣,就能夠實現多繼承的多態了。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
新聞熱點
疑難解答
圖片精選