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

  在VS2005编译器下,证明单个虚拟继承的内存布局:无论有无虚函数,必然含有虚基类表指针。虚基类表中的内容为本类实例的偏移和基类实例的相对偏移值。

   如果有虚函数,那么基类的虚函数表跟派生类的虚函数表是分开的。
  在内存布局上,地址从低到高,顺序如下:派生类的虚函数表指针,虚基类表指针,派生类的成员变量,基类的虚函数表指针,基类的成员变量。
也就是说派生类在上,基类在下。这个跟普通的继承相反。

  特别说明,GNU的GCC编译器在处理虚拟继承上跟VS有不同的地方。它的内存布局是:派生类的虚函数表跟虚基类表合并,另外分析。

  另外,发现如果派生类实现了基类的虚函数,那么派生类对象,派生类和基类的实例之间会多出一个值为0的间隔。

//VS编译器--单个虚拟继承.cpp
//2010.8.18
#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;}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;}private:int b;
};
//
int main()
{Derived obj;int** p = (int**)&obj;typedef void (__thiscall *fun)(void*pThis);//非常重要cout << "虚拟继承了基类的派生类的对象内存布局:" <<endl;for (int i = 0; i != sizeof(obj)/4; ++i){cout << p[i] << endl;}cout << endl << "第一虚函数表第一项,虚函数Derived::show2()地址:" << (int*)p[0][0] << endl;((fun)(p[0][0]))(p);cout << "第二虚函数表第一项,虚函数Base::show1()地址   :" << (int*)p[3][0] << endl;((fun)(p[3][0]))(p+3);cout << endl << "虚基类表第一项,本类对象地址 - 虚基类表指针地址 = " << (int*)p[1][0] << endl;cout << "虚基类表第二项,基类对象地址 - 虚基类表指针地址 = " << (int*)p[1][1] << endl;system("pause");return 0;
}
/*
Base::Base()
Derived::derived()
虚拟继承了基类的派生类的对象内存布局:
0041C2F8
0041C2FC
00000064
0041C2F0
0000000A第一虚函数表第一项,虚函数Derived::show2()地址:00401280
Derived::show2()
第二虚函数表第一项,虚函数Base::show1()地址   :00401250
Base::show1()虚基类表第一项,本类对象地址 - 虚基类表指针地址 = FFFFFFFC
虚基类表第二项,基类对象地址 - 虚基类表指针地址 = 00000008
请按任意键继续. . .
*/

C++对象内存布局--④VS编译器--单个虚拟继承相关推荐

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

    C++对象内存布局--⑤GCC编译器--单个虚拟继承 测试GNU的GCC编译器在处理虚拟继承上跟VS不同的地方.派生类的虚函数表跟虚基类表合并. //GCC编译器--单个虚拟继承.cpp //2010 ...

  2. C++对象内存布局测试总结

    C++对象内存布局测试总结 http://hi.baidu.com/����/blog/item/826d38ff13c32e3a5d6008e8.html 上文是半年前对虚函数.虚拟继承的理解.可能 ...

  3. 【C++】C++对象模型:对象内存布局详解(C#实例)

    C++对象模型:对象内存布局详解 0.前言 C++对象的内存布局.虚表指针.虚基类指针解的探讨,参考. 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可 ...

  4. C++ 对象内存布局 (4)

    注意:关于内存对齐(memory alignment),请看关于内存对齐问题,后面将会用到. 下面我们进行在普通继承(即非虚继承)时,派生类的指针转换到基类指针的情形研究.假定各类之间的关系如下图: ...

  5. 图说C++对象模型:对象内存布局详解

    目录 1.何为C++对象模型? 2.文章内容简介 3.理解虚函数表 3.1.多态与虚表 3.2.使用指针访问虚表 4.对象模型概述 4.1.简单对象模型 4.2.表格驱动模型 4.3.非继承下的C++ ...

  6. C++对象内存布局(转载)

    C++对象内存布局(转载) 转载地址:http://www.cppblog.com/stdyh/archive/2007/01/08/17442.html 写这个文章完全是因为想要搞清楚 vc 怎么布 ...

  7. C++对象内存布局--①测试虚函数表属于类

    C++对象内存布局--①测试虚函数表属于类 测试1:同一个类的多个对象共享同一张虚函数表.   //虚函数表.cpp //2010年8月18日 //测试虚函数表,说明虚函数表属于类所有.同一个类的多个 ...

  8. C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中

    C++对象内存布局--③测试多继承中派生类的虚函数在哪一张虚函数表中 测试2:证明派生类的虚函数的地址跟第一基类的虚函数地址保存在同一张虚函数表中. 派生类有多少个拥有虚函数的基类,派生类对象就有多少 ...

  9. C字节对齐与C++类对象内存布局

    一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...

最新文章

  1. Retrofit 网络请求参数注解@Path @Field @Query 等使用
  2. docker server 容器连接sql_Docker使用指南
  3. C#数据导出Excel详细介绍
  4. python字符串截取_Python容器类型公共方法汇总
  5. 线上日志分析与其他一些脚本
  6. 技术人凭什么那么骄傲?谢然:给自己开发工具
  7. Java10 新特性
  8. 注入域对象而不是基础结构组件
  9. linux命令创建硬链接,Linux终端命令接口(十一)硬链接与软连接
  10. linux查用户的家目录,详解Linux误删用户家目录的恢复方法
  11. PyOpenGL之3D界面详解(三)
  12. std::nothrow
  13. 瑞星企业防毒2010网络版(二)管理及应用
  14. 计算机指令窗口如何放大,我电脑每次打开一个窗口都好小,怎么设置为每次都全屏啊?...
  15. Maven项目 cityFileFK02数据库连接(课外完成)
  16. ISO三体系,招投标企业认证最多的资质
  17. 【杂烩】Tesla M40 24G 在Win11上的双显卡显示实现、改风冷
  18. 时间、日期的一些用法
  19. 网易邮箱数据遭泄露--拿什么保障个人互联网信息安全?
  20. HEIC格式是什么?

热门文章

  1. 内存泄漏Valgrind
  2. 用栈实现后缀表达式求解问题
  3. fasync驱动异步通知机制
  4. 每日一题:leetcode1579.保证图可完全遍历
  5. 九大经典算法之选择排序、堆排序
  6. MMKV集成与原理,吊打面试官系列!
  7. 计算星期c语言编码,[转载]计算任何一天是星期几的C语言源代码.
  8. Convolutional neural networks for artistic style transfer
  9. Github 简明教程 - 添加远程库
  10. 软件工程课设-----日程管理系统