注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

民主与科学

独立之人格,自由之思想

 
 
 

日志

 
 

C++虚函数表解析(高级篇)  

2015-05-21 17:30:41|  分类: C和C++语言 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
原文:http://blog.csdn.net/haoel
一、前言
在《C++虚函数表解析》中,对C++虚函数表进行了探讨,但是在谈论虚函数表里,至少有以下这些内容没有涉及:
1)有成员变量的情况。
2)有重复继承的情况。
3)有虚拟继承的情况。
4)有钻石型虚拟继承的情况。
 这篇文章将会是《C++虚函数表解析》的一个续篇,将以C++对象的内存布局为重点,也是一篇高级进阶的文章。大家在读这篇文章之前对C++有一定的基础和了解,并能先读C++虚函数表解析
二、对象内存布局的影响因素
 对象内存布局的影响因素主要有以下几项:
 1)成员变量
2)虚函数(产生虚函数表)
3)单一继承(只继承于一个类)
4)多重继承(继承多个类)
5)重复继承(继承的多个父类中其父类有相同的超类)
6)虚拟继承(使用virtual方式继承,为了保证继承后父类的内存布局只会存在一份)
上述的东西通常是C++这门语言在语义方面对对象内部的影响因素,当然,还会有编译器的影响(比如优化),还有字节对齐的影响。在这里我们都不讨论,我们只讨论C++语言上的影响。
 本篇文章着重讨论下述几个情况下的C++对象的内存布局情况。
 1)单一的一般继承(带成员变量、虚函数、虚函数覆盖)
2)单一的虚拟继承(带成员变量、虚函数、虚函数覆盖)
3)多重继承(带成员变量、虚函数、虚函数覆盖)
4)重复多重继承(带成员变量、虚函数、虚函数覆盖)
5)钻石型的虚拟多重继承(带成员变量、虚函数、虚函数覆盖)
 三、虚函数表复习
 我们简单地复习一下,我们可以通过对象的地址来取得虚函数表的地址,如:

           typedef void(*Fun)(void);
             Base b;
             Fun pFun = NULL;
             cout << "虚函数表地址:" << (int*)(&b) << endl;
            cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;
             // Invoke the first virtual function 
            pFun = (Fun)*((int*)*(int*)(&b));
            pFun();

我们同样可以用这种方式来取得整个对象实例的内存布局。因为这些东西在内存中都是连续分布的,我们只需要使用适当的地址偏移量,我们就可以获得整个内存对象的布局。
 本篇文章中的例程或内存布局主要使用如下编译器和系统:
1)Windows XP 和 VC++ 2003
2)Cygwin 和 G++ 3.4.4
四、深入C++对象的内存布局
单继承
关于单继承C++对象的内存布局请阅读《C++ 对象的内存布局(单继承)》和《C++虚函数表解析(基础篇)
多重继承
关于多重继承C++对象的内存布局请阅读《C++ 对象的内存布局(多重虚拟继承)》和《C++虚函数表解析(基础篇)
重复非虚拟继承
关于重复继承C++对象的内存布局请阅读《C++ 对象的内存布局(重复非虚拟继承)
重复虚拟继承
关于多重虚拟继承C++对象的内存布局请阅读《C++ 对象的内存布局(重复虚拟继承)
 
  评论这张
 
阅读(537)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017