zoukankan      html  css  js  c++  java
  • C++对象内存布局⑤GCC编译器单个虚拟继承

    C++对象内存布局--⑤GCC编译器--单个虚拟继承

      测试GNU的GCC编译器在处理虚拟继承上跟VS不同的地方。派生类的虚函数表跟虚基类表合并。

    //GCC编译器--单个虚拟继承.cpp
    //2010.8.18
    //虚基类表到底是那个?,还是说派生类的虚函数表的上边和下边都是?
    //GCC编译器
    #include <iostream>
    using   namespace std;
    //////////////////////////////////////////////////////////////////
    class Base
    {
        public:
            Base(int a = 10):a(a)
            {
                cout << "Base::Base()" << endl;
            }
            virtual void show1()
            {
                cout << "Base::show1()" << endl;
                cout << a << endl;
            }
        private:
            int a;
    };
    //////////////////////////////////////////////////////////////////
    class Derived : virtual public Base
    {
        public:
            Derived(int b = 100):b(b)
            {
                cout << "Derived::derived()" << endl;
            }
            virtual void show2()
            {
                cout << "Derived::show2()" << endl;
                cout << b << endl;
            }
        private:
            int b;
    };
    //////////////////////////////////////////////////////////////////
    int main()
    {
        Derived obj;
        int** p = (int**)&obj;
        cout << "虚拟继承了基类的派生类的对象内存布局:" <<endl;
        for (int i = 0; i != sizeof(obj)/4; ++i)
        {
            cout << p[i] << endl;
        }
         typedef void (*fun)(void*pThis);//this指针非常重要
        cout << endl << "第一虚函数表第一项,虚函数Derived::show2()地址:" << (int*)p[0][0] << endl;
        ((fun)(p[0][0]))(p);
        cout << "第二虚函数表第一项,虚函数Base::show1()地址   :" << (int*)p[2][0] << endl;
        ((fun)(p[2][0]))(p+2);
        cout << endl << "派生类虚函数表指针往低地址方向寻址:" << endl;
        cout << "p[0][-1] = " << (int*)p[0][-1] << endl;
        cout << "p[0][-2] = " << (int*)p[0][-2] << endl;
        cout << "p[0][-3] = " << (int*)p[0][-3] << endl;
    
        cout << endl << "派生类虚函数表指针往高地址方向寻址:" << endl;
        cout << "p[0][0] = " << (int*)p[0][0] << "(这个是show2()函数地址)" << endl;
        cout << "p[0][1] = " << (int*)p[0][1] << endl;
        cout << "p[0][2] = " << (int*)p[0][2] << endl;
        cout << "p[0][3] = " << (int*)p[0][3] << endl;
    
        cout << endl << "是否往高方向寻找和往地方向寻找所找到的都是虚基类表呢?" << endl;
        //system("pause");
        return 0;
    }
    /*
    Base::Base()
    Derived::derived()
    虚拟继承了基类的派生类的对象内存布局:
    0x472d4c
    0x64
    0x472d5c
    0xa
    
    第一虚函数表第一项,虚函数Derived::show2()地址:0x41cd50
    Derived::show2()
    100
    第二虚函数表第一项,虚函数Base::show1()地址   :0x41ccbc
    Base::show1()
    10
    
    派生类虚函数表指针往低地址方向寻址:
    p[0][-1] = 0x471388
    p[0][-2] = 0
    p[0][-3] = 0x8
    
    派生类虚函数表指针往高地址方向寻址:
    p[0][0] = 0x41cd50(这个是show2()函数地址)
    p[0][1] = 0
    p[0][2] = 0xfffffff8
    p[0][3] = 0x471388
    
    是否往高方向寻找和往地方向寻找所找到的都是虚基类表呢?
    */
    
    
  • 相关阅读:
    Springboot+mybatis-plus+mysql+clickhouse集成多数据源
    对集合里每个元素是一个对象,按照对象某一个属性值给这个集合排序
    vue的a-tree-select选择父节点回显的是子节点
    Es简单条件查询
    使用Ant Desigen在vue里面实现分页以及表头的模糊查询
    搭建第一个vue项目
    Address localhost:1099 is already in use
    spring的控制反转DI---基于注解实现
    mybatis下的ResultMap配置一对一以及一对多
    mybatis入门
  • 原文地址:https://www.cnblogs.com/cswuyg/p/1804087.html
Copyright © 2011-2022 走看看