深刻C++對象模型&虛函數表

多態的實現機制:安全

       C++中虛函數的主要做用就是用來實現多態,就是使用基類的指針或者引用調用重寫的虛函數,當父類的指針或引用指向父類對象時調用的是父類虛函數,當指向子類對象時調用的是子類的虛函數。那麼這又是怎麼實現的呢???ide

       這都是經過虛函數表實現的,虛函數表是經過一塊連續內存來存儲虛函數的地址。這張表解決了虛函數重寫(地址進行覆蓋)的問題 。在有虛函數的對象實例中都有一張虛函數表,虛函數表就像一張地圖,指明瞭實際調用的虛函數函數。函數

例:spa

class Base
{
public:
       Base()
              :_b(1){}
       virtual void fun1()
       { }
       virtual void fun2()
       { }
private:
       int _b;
};



虛函數表的最後一個元素是一個空指針。指針


       既然咱們知道了虛函數的地址,那麼就能夠經過過找到這塊地址來調用這個虛函數。這也致使了多態的不安全性,效率下降。orm

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




一、單繼承對象模型對象

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








二、多重繼承的對象模型繼承

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






三、菱形繼承的對象模型內存

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








四、菱形的虛擬繼承it

<span style="font-size:14px;">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>






相關文章
相關標籤/搜索