用cl.exe生成对象内存布局来学习虚函数

这篇文章所使用的方法来源于 CuteQt博客 上的一篇文章:http://www.cuteqt.com/blog/?p=868

生成对象内存布局所使用的方法来自于vc8编译器一个未公开的参数,即 /d1 reportSingleClassLayoutXXX或者 /d1 reportAllClassLayout,MSDN上关于这个的简单说明及示例可以见这里:http://blogs.msdn.com/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx

一般来说用reportSingleClassLayout,因为reportAllClassLayout会生成许多中间类的结果,干扰我们的分析。

按照上面博客中介绍的方法,一步步来跟踪各种虚函数使用情况下的对象内存布局,可以很直观的看到虚函数是怎样分布的,各种继承情况下虚函数是又是怎样生成的,等等。

一点简单的总结:

1。以前常说的,因为虚函数的使用,使得类多了一个vtable指针,大小增加了4字节,其实是不完全正确的。因为一个class内可能会有多个虚表的存在,比如当有多个带虚函数的父类时。

2。多个虚函数在虚表里的顺序由其定义顺序决定。如果是从多个父类派生来的,则这多个虚表的顺序由父类的申明顺序而定。

3。多继承情况下的同名虚函数处理使用了一种叫做thunk的技术,这样通过不同的基类调用同名的虚函数时,都会调用到相同的函数体内。

4。虚基类的实现多了一个vbi表,记录的是虚基类中的虚函数表地址信息。同时在派生类中计算好了到这个vbi表的偏移,这样虚基类里的虚函数在菱形继承关系的派生类中就只有了一份实现。

5。使用的时候其实不必要意这些细节问题,编译器在生成函数调用代码时已经帮我们处理好了,即这个函数在哪个虚表中,是第几个虚函数,最终也就是要做多少个字节的偏移。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值