• 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
    
    是否往高方向寻找和往地方向寻找所找到的都是虚基类表呢?
    */
    
    
  • 相关阅读:
    Linux上的.NET框架Mono 2.0发布
    WordPress数据库管理中五个实用的phpMyAdmin技巧
    美国十三个性价比较好的空间推荐 建站可优选
    众多站长将网站移民海外 该如何选择国外VPS
    Mono 开发 (使用.NET技术的你,绝对不能忽略Mono)
    数据库访问的性能问题与瓶颈问题【z】
    IE和FireFox中的event事件
    经典国外网站大放送
    AppScan 7.8.1 简体中文
    用lighttpd+mono在Linux上面跑ASP.NET程序
  • 原文地址:https://www.cnblogs.com/cswuyg/p/1804087.html
Copyright © 2020-2023  润新知