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

    在对象内存布局 (5)的代码中,在Derived类中覆盖Base1中声明的vfBase1_1(),其他代码不变。修改后的代码如下:

    #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;
        }
        inline void vfBase1_1()
        {
            cout << "This is in Derived::vfBase1_1()" << 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(Base2)/4;
        while(virtualFunctionPointer(tmp, i)&&i<2)
        {
            VFun pVF = virtualFunctionPointer(tmp, i++);
            pVF();
        }
        return 0;
    }

    运行结果:

    Derived对象值memory layout图解如下:

     

    我们可以看到,在Derived中overriden的虚函数Derived::vfBase1_1排在第一个虚函数表的第一位。虚函数Base::vfBase1_1()由于已经被overridden,所以在Derived对象的虚函数表中不再出现。

  • 相关阅读:
    第一次用NUnitAsp
    IT能够解决所有的商业问题吗?
    在这种东西里面,你会自在吗?
    看了段.net show之后的感想
    获取当前数据库中所有表的记录数
    对瀑布模型各阶段的解释
    Linux内核中的slab/slob/slub 在搞晕前先记下来
    分布式事务AT、TCC、Saga、XA 模式分析对比
    读懂Windows的“虚拟内存”为你量身定制
    示范NTFS 卷上的硬链接
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4091491.html
Copyright © 2011-2022 走看看