首页 > 代码库 > 深入C++对象模型&虚函数表

深入C++对象模型&虚函数表

多态的实现机制:

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



技术分享



技术分享


技术分享


本文出自 “11132019” 博客,转载请与作者联系!

深入C++对象模型&虚函数表