深度探索C++对象模型-Data语意学01
2016-12-09 11:05
471 查看
菱形继承实例
Ex:
继承关系如图:
sizeof X 的结果为1
sizeof Y 的结果为8
sizeof Z 的结果为8
sizeof A 的结果为12
注意:在VS2013下我的运行结果是1、4、4、8,原因是因为VS2013编译器对empty virtual base class提供了特殊支持,做了优化。原因稍后解释。
1、X的大小
X并不是空的,它有一个隐藏的1byte大小,那是被编译器安插进去的一个char。这使得这一class的不同实例化对象在内存中配置独一无二的地址。
Ex:X x1; X x2;x1和x2的地址不相同
2、Y和Z的大小
Y和Z的大小受到三个因素的影响:
(1)语言本身所造成的额外负担(overhead)
主要是虚拟继承,虚函数指针(vptr),虚函数表格(vtbl)造成的额外负担
(2)编译器对于特殊情况所提供的优化处理
某些编译器会对empty virtual base class提供特殊支持
(3)Alignment的限制
alignment就是将数值调整到某数的整数倍。在32位计算机上,通常alignment为4bytes(32位)
class Y和Z的大小目前为5 bytes。因为要对齐,所以最后的结果是8 bytes。
以下是Y和Z的对象布局
在一些新近的编译器中,一个empty virtual base class被视为derived class object最开头的一部分,也就是说它并没有花费任何的额外空间。因为既然有了members,就不需要原本为了empty class而安插的一个char。所以在此模型下,Y和Z的大小都是4。
以下是这种编译器的对象布局:
3、A的大小
一个virtual base class subobject只会在derived class中存在一份实例,不管它在class继承体系中出现了多少次!
class A的大小由以下几点决定:
(1)被大家共享的唯一一个class X实例,大小为1 byte
(2)Base class Y的大小,减去因virtual base class X而配置的大小,结果是4 bytes。
Base class Z的算法亦相同。加起来是8 bytes。
(3)class A自己的大小:0 byte
(4)class的alignment数量(如果有的话)。前述三项总和,表示调整前的大小是9 bytes。class A必须调整至4 bytes边界,所以需要填补3 bytes。结果是12 bytes。
如果是优化了empty virtual base class的编译器,class X实例的那1 byte将被拿掉,于是class A的大小为8 bytes。
注意:如果virtual base class X中放置一个(以上)的data members,两种编译器就会产生出完全相同的对象布局
static data members,则放置在程序的一个全局数据段,不会影响个别的class object的大小。在程序之中,不管该class被产生出多少个objects,static data members永远只存在一份实例。
Ex:
class X{}; class Y :public virtual X{}; class Z :public virtual X{}; class A :public Y, public Z{};
继承关系如图:
sizeof X 的结果为1
sizeof Y 的结果为8
sizeof Z 的结果为8
sizeof A 的结果为12
注意:在VS2013下我的运行结果是1、4、4、8,原因是因为VS2013编译器对empty virtual base class提供了特殊支持,做了优化。原因稍后解释。
1、X的大小
X并不是空的,它有一个隐藏的1byte大小,那是被编译器安插进去的一个char。这使得这一class的不同实例化对象在内存中配置独一无二的地址。
Ex:X x1; X x2;x1和x2的地址不相同
2、Y和Z的大小
Y和Z的大小受到三个因素的影响:
(1)语言本身所造成的额外负担(overhead)
主要是虚拟继承,虚函数指针(vptr),虚函数表格(vtbl)造成的额外负担
(2)编译器对于特殊情况所提供的优化处理
某些编译器会对empty virtual base class提供特殊支持
(3)Alignment的限制
alignment就是将数值调整到某数的整数倍。在32位计算机上,通常alignment为4bytes(32位)
class Y和Z的大小目前为5 bytes。因为要对齐,所以最后的结果是8 bytes。
以下是Y和Z的对象布局
在一些新近的编译器中,一个empty virtual base class被视为derived class object最开头的一部分,也就是说它并没有花费任何的额外空间。因为既然有了members,就不需要原本为了empty class而安插的一个char。所以在此模型下,Y和Z的大小都是4。
以下是这种编译器的对象布局:
3、A的大小
一个virtual base class subobject只会在derived class中存在一份实例,不管它在class继承体系中出现了多少次!
class A的大小由以下几点决定:
(1)被大家共享的唯一一个class X实例,大小为1 byte
(2)Base class Y的大小,减去因virtual base class X而配置的大小,结果是4 bytes。
Base class Z的算法亦相同。加起来是8 bytes。
(3)class A自己的大小:0 byte
(4)class的alignment数量(如果有的话)。前述三项总和,表示调整前的大小是9 bytes。class A必须调整至4 bytes边界,所以需要填补3 bytes。结果是12 bytes。
如果是优化了empty virtual base class的编译器,class X实例的那1 byte将被拿掉,于是class A的大小为8 bytes。
注意:如果virtual base class X中放置一个(以上)的data members,两种编译器就会产生出完全相同的对象布局
static data members,则放置在程序的一个全局数据段,不会影响个别的class object的大小。在程序之中,不管该class被产生出多少个objects,static data members永远只存在一份实例。
相关文章推荐
- 深度探索C++对象模型 Data语意学笔记
- 深度探索C++对象模型---data语意学
- 深度探索C++对象模型之Data语意学读书笔记
- 深度探索C++对象模型 第三章 Data 语意学
- 【C++】深度探索C++对象模型之构造、析构、拷贝语意学
- Inside the C++ Object Model 深度探索对象模型 3-DATA 4-Function
- 深度探索C++对象模型--Function语意学
- 深度探索C++对象模型:5.构造、析构、拷贝语意学
- 深度探索C++对象模型学习笔记——Function语意学
- 深度探索C++对象模型复习和学习 第六章:执行期语意学
- 【C++】深度探索C++对象模型之执行期语意学
- 深度探索C++对象模型 3Data语意学
- 深入探索C++对象模型笔记之六 —— Data语意学
- 深度探索C++对象模型学习 之 C++构造函数语意学(一)
- 深度探索C++对象模型之Data语义学小测试
- 深度探索C++对象模型 之 构造函数语意学
- 深度探索C++对象模型 第五章 构造、析构、拷贝语意学
- 深度搜索C++对象模型 Data 语意学-数据存取
- 深入探索C++对象模型:第三章 DATA语意学
- 深度探索C++对象模型 第二章构造函数语意学