您好,登錄后才能下訂單哦!
多態的實現機制:
C++中虛函數的主要作用就是用來實現多態,就是使用基類的指針或者引用調用重寫的虛函數,當父類的指針或引用指向父類對象時調用的是父類虛函數,當指向子類對象時調用的是子類的虛函數。那么這又是怎么實現的呢???
這都是通過虛函數表實現的,虛函數表是通過一塊連續內存來存儲虛函數的地址。這張表解決了虛函數重寫(地址進行覆蓋)的問題 。在有虛函數的對象實例中都有一張虛函數表,虛函數表就像一張地圖,指明了實際調用的虛函數函數。
例:
class Base { public: Base() :_b(1){} virtual void fun1() { } virtual void fun2() { } private: int _b; };
虛函數表的最后一個元素是一個空指針。
既然我們知道了虛函數的地址,那么就可以通過過找到這塊地址來調用這個虛函數。這也導致了多態的不安全性,效率降低。
typedef void (* pfun)(); void PrintfBase(pfun *_ppfun) { int i = 0; for (i = 0; _ppfun[i] != NULL; i++) { _ppfun[i] (); } } void test() { Base b; PrintfBase((pfun *)*((int *)(&b))); }
1、單繼承對象模型
class Base { public: Base() :_b(1){} virtual void fun1() { cout << "Base::fun1()" <<endl; } virtual void fun2() { cout << "Base::fun2()" << endl; } private: int _b; }; class Deriver :public Base { public: Deriver() :_d(2){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun3() { cout << "Deriver::fun3()" << endl; } private: int _d; }; typedef void (* pfun)(); void PrintfBase(pfun *_ppfun) { int i = 0; for (i = 0; _ppfun[i] != NULL; i++) { _ppfun[i] (); } } void test() { Base b; PrintfBase((pfun *)*((int *)(&b))); }
2、多重繼承的對象模型
class Base1 { public: Base1() :_b1(1){} virtual void fun1() { cout << "Base1::fun1()" <<endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; } private: int _b1; }; class Base2 { public: Base2() :_b2(2){} virtual void fun1() { cout << "Base2::fun1()" << endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; } private: int _b2; }; class Deriver :public Base1,public Base2 { public: Deriver() :_d3(3){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun3() { cout << "Deriver::fun3()" << endl; } private: int _d3; };
3、菱形繼承的對象模型
class Base { public: Base() :_b1(1){} virtual void fun1() { cout << "Base1::fun1()" << endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; } private: int _b1; }; class Base2:public Base { public: Base2() :_b2(1){} virtual void fun1() { cout << "Base2::fun1()" << endl; } virtual void fun3() { cout << "Base2::fun2()" << endl; } private: int _b2; }; class Base3:public Base { public: Base3() :_b3(1){} virtual void fun1() { cout << "Base3::fun1()" << endl; } virtual void fun3() { cout << "Base3::fun2()" << endl; } private: int _b3; }; class Deriver:public Base2,public Base3 { public: Deriver() :_d3(3){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun4() { cout << "Deriver::fun3()" << endl; } private: int _d3; };
4、菱形的虛擬繼承
<span >class Base { public: Base() :_b1(1){} virtual void fun1() { cout << "Base1::fun1()" << endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; } private: int _b1; }; class Base2:virtual public Base { public: Base2() :_b2(2){} virtual void fun1() { cout << "Base2::fun1()" << endl; } virtual void fun3() { cout << "Base2::fun2()" << endl; } private: int _b2; }; class Base3:virtual public Base { public: Base3() :_b4(3){} virtual void fun1() { cout << "Base3::fun1()" << endl; } virtual void fun3() { cout << "Base3::fun2()" << endl; } private: int _b3; }; class Deriver:public Base2,public Base3 { public: Deriver() :_d3(4){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun4() { cout << "Deriver::fun4()" << endl; } private: int _d4; };</span>
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。