C++类对象内存模型与成员函数调用分析.pdf

  1. 1、本文档共24页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
C类对象内存模型与成员函数调用分析

C++类对象内存模型与成员函数调用分析 C++类对象内存模型是一个比较抓狂的问题,主要是C++特性太多了,所以必须建立一个清晰的分析层次。一般而言,讲到 C++对象,都比较容易反应到以下这个图表: 这篇文章,就以这个表格作为分析和行文的策略的纵向指导;横向上,兼以考虑无继承、单继承、多重继承及虚拟继承四方面情况,这样一来,思维层次应该算是比较清晰 了。 1、C++类数据成员的内存模型 1.1 无继承情况 实验最能说明问题了,首先考虑下面一个简单的程序 1: #includeiostream class memtest { public : memtest (int _a, double _b) : a (_a), b (_b) {} inline void print_addr (){ std::coutAddress of a and b is:/n/t/ta/n/t/t b/n; } inline void print_sta_mem (){ std::coutAddress of static member c is:/n/t/tc/n; } private : int a; double b; static int c; }; int memtest ::c = 8; int main () { memtest m (1,1.0); std::coutAddress of m is : /n/t/t m/n; m .print_addr (); m .print_sta_mem (); return 0; } 在GCC4.4.5 下编译,运行,结果如下: 可以发现以下几点: 1. 非静态数据成员a 的存储地址就是从类的实例在内存中的地址中(本例中均为0xbfadfc64)开始的,之后的doubleb 也紧随其后,在内存中连续存储; 2. 对于静态数据成员c,则出现在了一个很“莫名其妙”的地址0x804a028 上,与类的实例的地址看上去那是八竿子打不着; 其实不做这个测试,关于C++数据成员存储的问题也都是C++ Programmer 的常识,对于非静态数据成员,一般编译器都是按其在类中声明的顺序存储,而且数据成员的起始地 址就是类得实例在内存中的起始地址,这个在上面的测试中已经很明显了。对非静态数据成员的读写,我们可以这样想,其实 C++程序完全可以转换成对应的C 程序来编写, 有一些C++编译器编译C++程序时就是这样做的。对非静态数据成员的读写也可以借助这个等价的 C 程序来理解。考虑下面代码段2 : // C++ code struct foo{ public : int get_data () const{ return data; } void set_data(int _data){ data = _data;} private: int data; }; foo f(); int d = f.get_data(); 如果要你用C 你会怎么实现呢? // C code struct foo{ int data; }; int get_foo_data (const foo* pFoo){ return pFoo-data;} void set_foo_data (foo* pFoo, int _data){ pFoo-data = _data;} foo f; f.data = 8; foo* pF = f; int d = get_foo_data (pF); 在C 程序中,我们要实现同样的功能,必须是要往函数的参数列表中压入一个指针作为实参。实际上C++在处理非静态数据成员的时候也是这样的,C++必须借助一个直接的 或暗喻的实例指针来读写这些数据,这个指针,就是大名鼎鼎的 this 指针。有了this 指针,当我们要读写某个数据时,就可以借助一个简单的指针运算,即this 指针的地址加上 该数据成员的偏移量,就可以实现读写了。这个偏移量由C++编译器为我们计算出来。 对于静态数据成员,如果在static_mem.cpp 中加入下面一条语句: std::cout”Size of class memtest is : ”sizeof (memtest)”/n”; 我们得到

文档评论(0)

yaocen + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档