深度探索C++对象模型之第三章:data语义学中对象布局
来源:互联网 发布:java基础书记 编辑:程序博客网 时间:2024/06/04 19:01
说明: 看到 http://www.roading.org/?p=545 已经整理的很好了,所以前部分大部分引用原文,感谢原作者@~@,后半部分主要引用自书本
类对象占用的内存空间可能比我们想象的要大,有如下原因:
(1) 由编译器自动加上额外的data memebers,用以支持某些语言特性(主要是各种virtual特性)
(2)因为边界调整(alignment)的需要(详细请看:内存对齐的理解)
下面给出个实例:
class X{};class Y:virtual public X{};class Z:virtual public X{};class A:public Y, public Z{};
Lippman的一个法国读者的结果是: vs2008/2010上的结果是:
sizeof X yielded 1 sizeof X yielded 1
sizeof Y yielded 8 sizeof Y yielded 4
sizeof Z yielded 8 sizeof Z yielded 4
sizeof A yielded 12 sizeof A yielded 8
(下面要对这两个不同的结果进行分析)
对于像X这样的一个的空类,编译器会对其动点手脚——隐晦的插入一个字节。为什么要这样做呢?插入了这一个字节,那么X的每一个对象都将有一个独一无二的地址。如果不插入这一个字节那对X的对象取地址的结果是什么?两个不同的X对象间地址的比较怎么办?我们再来看Y和Z。首先我们要明白的是实现虚继承,将要带来一些额外的负担——额外需要一个某种形式的指针。到目前为止,对于一个32位的机器来说Y、Z的大小应该为5,而不是8或者4。我们需要再考虑两点因素:alignment和编译器的优化。
我们再来看Y和Z。首先我们要明白的是实现虚继承,将要带来一些额外的负担——额外需要一个某种形式的指针。到目前为止,对于一个32位的机器来说Y、Z的大小应该为5,而不是8或者4。我们需要再考虑两点因素:alignment和编译器的优化。
alignment(内存对齐的理解)会将数值调整到某数的整数倍,32位计算机上位4bytes(32位)。内存对齐可以使得总线的运输量达到最高效率。所以Y、Z的大小被补齐到8就不足为奇了。
那么在vs2010中为什么Y、Z的大小是4而不是8呢?我们先思考一个问题,X之所以被插入1字节是因为本身为空,需要这一个字节为其在内存中给它占领一个独一无二的地址。但是当这一字节被继承到Y、Z后呢?它已经完全失去了它存在的意义,为什么?因为Y、Z各自拥有一个虚基类指针,它们的大小不是0。既然这一字节在Y、Z中毫无意义,那么就没必要留着。也就是说vs2010对它们进行了优化,优化的结果是去掉了那一个字节,而Lippman的法国读者的编译器显然没有做到这一点。
当我们现在再来看A的时候,一切就不是问题了。对于那位Lippman的法国读者来说,A的大小是共享的X实体1字节,X和Y的大小分别减去虚基类带来的内存空间,都是4。A的总计大小为9,alignment以后就是12了。而对于vs2010来说,那个一字节被优化后,A的大小为8,也不需再进行alignment操作。
下面讲下类中存在数据成员和继承关系时类对象中的内存分配:
假设有如下三个类:
class Concrete1{ public://.... private:int val;char bit1;};class Concrete2 : public Concrete1{ public://.... private:char bit2;};class Concrete3 : public Concrete2{ public://... private:char bit3;};
以32为机器为例,在上述类中:
(1)Concrete1内含两个members: val 和bit1, 加起来是5个字节。边界对齐填充后Concrete1对象实际占用8个字节.
(2)很多人错误的认为Concrete2只加了一个char类型,大小为5+1 + 3(边界对齐) = 8个字节。 其实Concrete2 占用了12个字节。即Concrete1的填充空间仍然存在 8 + 1 = 9 根据边界对齐,再加上3个字节。 Concrete2 占用了12个字节。
(3)相同的道理Concrete3 对象占用16字节
以上中Concrete2其实是浪费6个字节来填补空间。Concrete3浪费12个字节来填补空间。
以下面一组图来说明这三个类的对象布局:
原因下载还没有看明白,等明白后再续在原书:P106
- 深度探索C++对象模型之第三章:data语义学中对象布局
- 深度探索C++对象模型----Data语义学
- 深度探索C++对象模型-Data语义学
- 深度探索C++对象模型之Data语义学小测试
- [读书笔记] 深入探索C++对象模型-第三章 Data语义学(中)
- 深度探索C++对象模型复习和学习 第三章 Data 语义学(The Semantics of Data )
- 《深度探索c++对象模型》 学习笔记 - 3 data语义学
- [读书笔记] 深入探索C++对象模型-第三章 Data语义学(上)
- [读书笔记] 深入探索C++对象模型-第三章 Data语义学(下)
- 深度探索C++对象模型第二章 构造函数语义学
- 深度探索C++对象模型第六章 执行其语义学
- 深度探索C++对象模型第三章 Data 语意学
- 《深度探索C++对象模型》第三章 Data语意学
- 深度探索C++对象模型系列笔记之第二章:构造函数语义学
- 《深度探索c++对象模型》 学习笔记 - 4 Function语义学
- 深度探索C++对象模型--构造函数语义学
- 深度探索C++对象模型-构造函数语义学
- 《深度探索C++对象模型》:Data member的布局
- 一、Bitmap的recycle问题
- error和exception的区别,RuntimeException和非RuntimeException的区别
- 系统调用跟我学
- CentOS安装libpcap
- 摄像头的YUV
- 深度探索C++对象模型之第三章:data语义学中对象布局
- flex URLRequest 加载XML
- FW:推荐一些国外嵌入式开发的网站
- NPN PNP开关电路
- linux驱动学习——怎么自动创建设备文件
- Flash Builder 4 安装后Eclipse变成中文了怎么解决
- Javascript小结
- C#索引器是封装性的体现
- sed命令