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

    如果在对象内存布局 (5)的代码中,将Base1中的两个虚函数声明删除,同时将main函数中的下面代码注释掉(因为现在只有两张虚函数表了):

    代码如下:

    #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)+sizeof(Base2))/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(Base2)/4;
        while(virtualFunctionPointer(tmp, i)&&i<2)
        {
            VFun pVF = virtualFunctionPointer(tmp, i++);
            pVF();
        }*/
        return 0;
    }

    运行结果:

    通过修改代码的位置以及运行结果可以知道,Derived对象的memory layout图解如下:

    由上面分析可知:

    其一,Base1 subobject排列在Base2 subobject之后,而在Base3 subobject之前,尽管它在Derived类的继承列表中排列在首位,因为它已经没有虚函数表了,但仍然排列在Derived类的成员变量m_derived之前。

    其二,在Derived类中定义的虚函数Derived::vfDerived()附加在一个虚函数表的最后,这时第一张虚函数表是类Base2的。

  • 相关阅读:
    平面切圆柱面的椭圆绘制
    抛物面倾斜体积积分
    计算误差函数的积分--erf(x)
    三棱椎的体积
    Mac平台上OpenCV开发环境搭建
    仿新浪右下角视频弹窗(视频弹出广告)播放器
    python爬虫之Scrapy 使用代理配置
    ip地址定位库
    python 使用 redis expire属性设置访问时间间隔
    如何做将两张图片合二为一
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4091424.html
Copyright © 2011-2022 走看看