• 对象内存布局 (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的。

  • 相关阅读:
    ubuntu14.4开启ftp服务
    ubuntu14.4安装gtx970显卡驱动的艰辛历程
    jquery.dataTables的用法
    win7上安装theano keras深度学习框架
    使用BeanUtils设置属性转换String到Date类型
    keras在win7下环境搭建
    Python-try except else finally有return时执行顺序探究
    MySQL-EXPLAIN用法详解
    PHP-Windows下搭建Nginx+PHP环境
    PHP-php.ini中文版
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4091424.html
Copyright © 2020-2023  润新知