zoukankan      html  css  js  c++  java
  • 对象内存布局 (5)

    内容概要:

    满足下面3个条件时,

    1. 父类有虚函数,子类也有虚函数,且子类的虚函数重写或覆盖了父类的虚函数

    2. 非虚继承

    3. 多重继承

    类对象之内存布局

    多重继承,派生类不重写基类中的虚函数。

    假定各类之间的关系如下图:

       

    代码如下:

    #include <iostream>
    using namespace std;
    
    class Base1
    {
    public:
        int m_base1;
        inline virtual void vfBase1_1()
        {
            cout << "This is in Base1::vfBase1_1()" << endl;
        }
        inline virtual void vfBase1_2()
        {
            cout << "This is in Base1::vfBase1_2()" << endl;
        }
    };
    class Base2
    {
    public:
        int m_base2;
        inline virtual void vfBase2_1()
        {
            cout << "This is in Base2::vfBase2_1()" << endl;
        }
        inline virtual void vfBase2_2()
        {
            cout << "This is in Base2::vfBase2_2()" << endl;
        }
    };
    class Base3
    {
    public:
        int m_Base3;
        inline virtual void vfBase3_1()
        {
            cout << "This is in Base3::vfBase3_1()" << endl;
        }
        inline virtual void vfBase3_2()
        {
            cout << "This is in Base3::vfBase3_2()" << endl;
        }
    };
    class Derived : public Base1, public Base2, public Base3
    {
    public:
        int m_derived;
        inline virtual void fd()
        {
            cout << "This is in Derived::fd()" << endl;
        }
    };
    typedef void (*VFun)(void);
    template<typename T>
    VFun virtualFunctionPointer(T* b, int i)
    {
        return (VFun)(*((int*)(*(int*)b) + i));
    }
    int main(void)
    {
        Derived d;
        cout << "The size of Derived object = 	" << sizeof(Derived) << endl;
        cout << endl;
        cout << "1st virtual function table: " << endl;
        int i = 0;
        while(virtualFunctionPointer(&d, i)&&i<3)
        {
            VFun pVF = virtualFunctionPointer(&d, i++);
            pVF();
        }
        cout << endl;
        cout << "2nd virtual function table: " << endl;
        i = 0;
        //以32字长的机器,找到下一个继承base class的vptr
        int* tmp = ((int*)&d)+ sizeof(Base1)/4;
        //虚函数表中的虚函数后面不为NULL?如果不加i的限制会出现段错误,不能结束循环
        while(virtualFunctionPointer(tmp, i)&&i<2)
    
        {
            VFun pVF = virtualFunctionPointer(tmp, i++);
            pVF();
        }
        cout << endl;
        cout << "3rd virtual function table: " << endl;
        i = 0;
        tmp = ((int*)&d) +(sizeof(Base1)+sizeof(Base2))/4;
        while(virtualFunctionPointer(tmp, i)&&i<2)
        {
            VFun pVF = virtualFunctionPointer(tmp, i++);
            pVF();
        }
        return 0;
    }

    运行结果:

    Derived对象之memory layout如下:

     (表中的Base::vfBase1_1应该是Base1::vfBase1_1,其余的类推)

    由上面的分析可知:

    其一:有三个虚函数表

    其二:在Derived类中定义的虚函数Derived::vfDerived()附加在一个虚函数表的最后

     (注意:多重继承有多个虚函数表)

  • 相关阅读:
    附加目录中所有的数据库文件
    SQL Server 2008中的GROUPING SETS的应用实例
    Gmail式的上传
    ubuntu9.10下配置需要用户名及密码的上网代理(squid)
    【jQuery】仿IPhone的滑动操作效果
    Ubuntu9.10下Nginx+PHP(Fastcgi) 安装过程
    如何从SQL Server 中取得字段说明
    SQL server 2005 更改数据库名称
    ASP通过SMTP发邮件
    数据库镜像出现“无法访问或不存在"故障的原因和解决方案
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4091164.html
Copyright © 2011-2022 走看看