您好,登錄后才能下訂單哦!
多態(tài)的實(shí)現(xiàn)機(jī)制:
C++中虛函數(shù)的主要作用就是用來(lái)實(shí)現(xiàn)多態(tài),就是使用基類(lèi)的指針或者引用調(diào)用重寫(xiě)的虛函數(shù),當(dāng)父類(lèi)的指針或引用指向父類(lèi)對(duì)象時(shí)調(diào)用的是父類(lèi)虛函數(shù),當(dāng)指向子類(lèi)對(duì)象時(shí)調(diào)用的是子類(lèi)的虛函數(shù)。那么這又是怎么實(shí)現(xiàn)的呢???
這都是通過(guò)虛函數(shù)表實(shí)現(xiàn)的,虛函數(shù)表是通過(guò)一塊連續(xù)內(nèi)存來(lái)存儲(chǔ)虛函數(shù)的地址。這張表解決了虛函數(shù)重寫(xiě)(地址進(jìn)行覆蓋)的問(wèn)題 。在有虛函數(shù)的對(duì)象實(shí)例中都有一張?zhí)摵瘮?shù)表,虛函數(shù)表就像一張地圖,指明了實(shí)際調(diào)用的虛函數(shù)函數(shù)。
例:
class Base { public: Base() :_b(1){} virtual void fun1() { } virtual void fun2() { } private: int _b; };
虛函數(shù)表的最后一個(gè)元素是一個(gè)空指針。
既然我們知道了虛函數(shù)的地址,那么就可以通過(guò)過(guò)找到這塊地址來(lái)調(diào)用這個(gè)虛函數(shù)。這也導(dǎo)致了多態(tài)的不安全性,效率降低。
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、單繼承對(duì)象模型
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、多重繼承的對(duì)象模型
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、菱形繼承的對(duì)象模型
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>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。