哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleClassLayout/d1reportAllClassLayout 。看个复杂的例子吧(如下),现在假设我们想知道Derived类的对象布局,怎么办? 在Project Properties->C++->Command Line->Additional Options里面加上/d1reportSingleClassLayoutDerived吧!

;

}

F5编译之,你会惊奇地发现,Output里面有如下字样:


到了吗? VC8居然输出了Derived对象的完整布局!
我们终于可以不必两眼一抹黑般的去peek/poke了....第1行表明,Derived对象总占用了32字节;其由三部分组成,分别是行3-行7、行
8-行12、行13、行28;其中前二者分别是基类Base1、Base2的布局,最后的行28为虚拟基类Common的布局。

以基类
Base1部分为例,可发现其由一个虚函数表指针vftable和虚基表指针vbtable构成,先看Base1部分的vftable所指向的虚
表$vftable@Base1(行19),不难发现,其中的表项2已经被Derived::print2给override了;再来看Base2部分的
vftable所指向的虚表$vftable@Base2(行23),可发现,同样的,Base2::dump2被Derived::dump2给
override了。这不明摆着就是虚函数机制嘛,heh~

值得注意的是,这个例子同时说明,多继承场合下,其实在单一对象中是存在多个
this指针的....行35-36给出了如何将Derived的this指针校正为其基类子对象this指针的偏移量,也就是说,根据行36,假设有个
Derived
d,那么d.dump1()实际上应该理解成通过虚表$vftable@Base2对((Base2*)
(((char*)&d)+12))->dump1()的调用....即传递给所有Base2成员函数的this指针应该是
(Base2*)((char*)(&d)+12),这里可能我写得恐怖了点,意思到了就成....这不,普通继承、多继承、对象Slicing
的语义都在这个布局里面了,看仔细了哈~

OK,多继承看完了,继续看虚拟基类是如何布局的。虚基Common在Derived的布局中,
位于Derived本身数据成员之后的位置。Base1、Base2中均保存了一个vbtable指针,其分别指向各自所使用的虚基
表$vbtable@Base1和$vbtable@Base2,为什么要指向一个虚基表?
很简单,因为Base1、Base2有可能会同时继承多个不同的虚拟基类.....这充分体现了C++对象布局的复杂性....在每个虚基表中,保存了所
继承的虚拟基类部分相对于子类部分vbtable指针的偏移值,以Base2为例,我们知道Base2的vbtable在Derived中的偏移值为
16(行10),则根据$vbtable@Base2,虚基Common部分距离Base2
vbtable指针的偏移值为12,则有虚基Common在Derived中的总偏移值为16+12。与普通多继承同理,我们在调用非虚拟的虚基成员函数
时,必须将Derived的this指针调整为指向虚基部分的this指针,只有这样才能成功地访问虚基自身的数据成员和虚基的虚拟函数(通过虚基自己的
vftable,为简单起见,上例中我就没弄那么复杂了,大家可以自己玩玩,明白如何举一反三即可)

看完了上述解释,是不是感觉比啃Inside C++ Object Model来得更快更直观啊?heh

Visual C++ 8.0对象布局的更多相关文章

  1. Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承(VC直接输出内存布局)

    原文:VC8_Object_Layout_Secret.html 哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleCl ...

  2. visual studio2013 C++查看对象布局

    一在visual studio中进行设置,可以方便的查看对象的内存布局 右键所要显示的*.cpp >> 属性 >> 命令行 >> 其它选项 在其他选项中添加: /d ...

  3. VC++对象布局的奥秘:虚函数、多继承、虚拟继承

    哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleClassLayout和/d1reportAllClassLayout ...

  4. Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)

    Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...

  5. C++ 类继承的对象布局

    C++多重继承下,对象布局与编译器,是否为虚拟继承都有很大关系,下面将逐一分析其中的差别,相同点为都按照类继承的先后顺序布局(类内按照虚表.成员声明先后顺序排列).该类情况为子类按照继承顺序排列,如c ...

  6. 基于Visual C++6.0的DLL编程实现

    整理自基于Visual C++6.0的DLL编程实现 本文通过通俗易懂的方式,全面介绍了动态链接库的概念.动态链接库的创建和动态链接库的链接,并给出个简单明了的例子,相信读者看了本文后,能够创建自己的 ...

  7. Xamarin For Visual Studio 3.0.54.0 完整离线破解版

    Xamarin For Visual Studio 3.0.54.0 完整离线破解版 Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xama ...

  8. 转 Visual C++6.0 与matlab联合编程(2)----Visual C++6.0 环境下编译和调试MEX文件

    我的最初想法是利用matlab的mex命令调用C++程序生成动态链接库的,但是测试程序(文中另附)通过了,自己的实际应用程序却没有过.还是把方法贴在这儿,以便自己以后进行整理. http://shij ...

  9. win7+python3.6+word_cloud 安装出现Microsoft Visual C++ 14.0 is required

    说明 环境: 已安装Anaconda3 (64-bit) 4.4.0(Python 3.6.1).其中,代码调试在Spyder 3.1.4中进行,安装包则直接打开Anaconda Prompt调用cm ...

随机推荐

  1. [译]C语言实现一个简易的Hash table(1)

    说明 Hash table翻译过来就是Hash表,是一种提供了类似于关联数组的数据结构,可以通过key执行搜索.插入和删除操作.Hash表由一些列桶(buckets)组成,而每一个bucket都是由k ...

  2. PHP读取excel表格,和导出表格

    读取表格 public function excel(){ import("Common.Vendor.Excel.PHPExcel"); $filename="./fi ...

  3. java.io.FileNotFoundException:file:\D:\code\xml-load\target\XX.jar!\XXX(文件名、目录名或卷标语法不正确。)

    1.当使用Spring Boot将应用打成jar时,需要读取resources目录下配置文件时,通常使用ClassLoader直接读取,通常建议使用这种方式,直接将xml文件读成流传入 // 加载xm ...

  4. Arduino上“Collect2.exe: error: ld returned 5 exit status”错误的解决方法

    1.运行环境 Windows xp; Arduino1.6.11 IDE. 2.问题 在Arduino编译时,经常出现如下的错误: collect2.exe: error: ld returned 5 ...

  5. 领扣-两数之和-Python实现

    领扣每日一题 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...

  6. linux查看文件命令tail的使用

    一.介绍 linux tail命令用途是依照要求将指定的文件的最后部分输出到终端中,通俗讲来,就是把某个档案文件的最后几行显示到终端上,假设该档案有更新,tail会自己主动刷新,确保你看到最新的档案内 ...

  7. Kali linux 安装

    df -m umount  /media exit

  8. 深度学习开源库tiny-dnn的使用(MNIST)

    tiny-dnn是一个基于DNN的深度学习开源库,它的License是BSD 3-Clause.之前名字是tiny-cnn是基于CNN的,tiny-dnn与tiny-cnn相关又增加了些新层.此开源库 ...

  9. LOJ #2585. 「APIO2018」新家

    #2585. 「APIO2018」新家 https://loj.ac/problem/2585 分析: 线段树+二分. 首先看怎样数颜色,正常的时候,离线扫一遍右端点,每次只记录最右边的点,然后查询左 ...

  10. CF 547 D. Mike and Fish

    D. Mike and Fish http://codeforces.com/contest/547/problem/D 题意: 给定平面上n个点,将这些点染成红或者蓝色,要求每行.每列红色点与蓝色点 ...