Data 语意学

class X {};
class Y : public virtual X {};
class Z : public virtual X {};
class A : public virtual Z {};
sizeof(X) // result 1
sizeof(Y) // result 8
sizeof(Z) // result 8
sizeof(A) // result 12

空的class隐藏一个1byte大小,编译器安插进去的一个char,这使得这一class的object得以在内存中配置独一无二的地址。
Y和Z的大小与机器有关,也会编译器有关。事实上,Y和Z的大小受到三个因素的影响:

  1. 语言本身所造成的额外负担(overhead) virtual base class导致一些额外负担,反映在某种形式的指针身上,它或者指向virtual base class suboject,或者指向一个相关表格:表格中存放的若不是virtual base class suboject的地址,就是其偏移位置(offset)。
  2. 编译器对于特殊情况所提供的优化处理 virtual base class X subobject的1 bytes 大小也出现在class Y 和 Z身上。传统上它被放在derived class的固定部分的尾端。某些编译器会对empty virtual base class提供特殊支持。
  3. alignment的限制 聚合的结构体大小受到alignment的限制,使它们能够更有效地在内存中被存取。alignment 是4bytes,所以class Y和Z必须填补3bytes。最终得到的结果就是8 bytes。

在这里插入图片描述

某些特殊处理,一个empty virtual base class 被视为derived class object最开头的一部分,也就是说它并没有花费任何的额外空间。这就节省了第二点1bytes,因为既然有了members,就不需要原本为了empty class 而安插的一个char,也就不需要第三点所说的3bytes的填补。只剩下第一点所说的额外负担。在此模型下。Y和Z的大小都是4而不是8.
在这里插入图片描述

没有特殊处理,A的大小:

  1. 被大家共享的唯一一个class X实例,大小为1 bytes;
  2. Base class Y的大小,减去“因virtual base class X而配置”的大小,结果是4 bytes。Base class Z的算法亦同。加起来是8 bytes;
  3. class A 的alignment数量(如果有的话)。前述三项总和,表示调整前的大小是9 bytes。class A 必须调整至4 bytes边界,所以需要调补3bytes,结果是12bytes。
    特殊处理,A的大小:

class X实例的那1 byte将被拿掉,于是额外的3bytes填补额也不必了,因此class A的大小将是8 bytes。
Nonstatic data members 放置的是“个别的class object”感兴趣的数据,static data members则放置的是“整个class”感兴趣的事;
Nonstatic data members 把数据直接存放在每一个class object之中。对于继承而来的nonstatic data members也是如此,不过是virtual 还是nonvirtual base class 也是如此。不过并没有强制定义其间的排列顺序。static data member 则被放置在程序的一个global data segment中,不会影响个别的class object大小。在程序中,不管该class被产生出多少个objects(经由直接产生或间接派生)。static data members永远只存在一份实例(甚至即使该class没有object实例,其static data members也已存在)。但是一个template class的static data members的行为稍有不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值