溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

深入C++對(duì)象模型&虛函數(shù)表

發(fā)布時(shí)間:2020-06-22 16:17:29 來(lái)源:網(wǎng)絡(luò) 閱讀:700 作者:我是你帆哥 欄目:編程語(yǔ)言

多態(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)));
}

深入C++對(duì)象模型&虛函數(shù)表




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)));
}



深入C++對(duì)象模型&虛函數(shù)表

深入C++對(duì)象模型&虛函數(shù)表



深入C++對(duì)象模型&虛函數(shù)表




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;
};


深入C++對(duì)象模型&虛函數(shù)表

深入C++對(duì)象模型&虛函數(shù)表

深入C++對(duì)象模型&虛函數(shù)表



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;
};




深入C++對(duì)象模型&虛函數(shù)表


深入C++對(duì)象模型&虛函數(shù)表


深入C++對(duì)象模型&虛函數(shù)表



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>



深入C++對(duì)象模型&虛函數(shù)表



深入C++對(duì)象模型&虛函數(shù)表


深入C++對(duì)象模型&虛函數(shù)表


向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI