现在的位置: 首页 > 综合 > 正文

《深度探索C++对象模型》读书笔记之Data语意学

2013年11月24日 ⁄ 综合 ⁄ 共 1293字 ⁄ 字号 评论关闭

1、 
Data member的布局是怎样的?

非静态数据成员

1>    在同一个Access
Section
(也就是private,public,protected等区段)中,较晚出现的数据成员在classobject中有较高的地址。

2>    允许编译器将同一类型的多个Acess
Section
的顺序自由排列,而不必在乎它们的声明次序(但似乎没有编译器这样做)。

 静态数据成员

1>    静态数据成员存放在程序的data
segment
中,和个别的class object无关。

 

2、 
Data member的存取会不会有额外的代价?

1>    静态数据成员:static
data members
被编译器提出于class之外,并被视为一个global变量(但只在class生命范围内可见)。每一个member的存取许可(privatepublicprotected),以及与class的关联,并不会导致任何空间上或者执行时间上的额外负担。

2>    非静态数据成员:想要对一个nonstatic
data member
进行存取操作,编译器需要把class object的起始地址加上data member的偏移量。每个nonstatic
data member
的偏移量在编译时期即可获知,甚至如果member属于一个base
classsubobject
(多继承)也是一样。因此存取一个nonstatic data member,其效率和存取一个C
struct member
或者一个nonderived classmember是一样的。

备注:如果存取操作涉及到虚继承中的指针/引用存取则会导入一层间接性。因为不知道指针指向的对象或者引用的对象的具体类型,所以存取操作需要延迟至执行期,经由一个额外的间接导引才能解决。

 

3、 
Data member在继承、拥有虚函数(即、多态)、虚继承的情况下的布局对subobject的数据成员的存取(或派生类对象转型为基类类型)的影响是怎样的?

1>    单一继承不包含虚函数:与普通的C结构体布局一致,因此没有任何额外的空间和存取负担。

2>    单一继承并含有虚函数:数据成员存取(转型)无影响,当然虚函数的调用的负担则不可避免(将虚函数表指针布局在class首尾均是如此)。

3>    多继承:不同于单一继承,问题主要发生于derived
class object
和其第二或者后继的base class objects之间的转换。不论是直接转换还是由其所支持的virtual
function
机制做转换。由于members的位置在编译时就确定了,所以存取members只需要一个简单的offset运算(加上或减去介于中间的base
class subobject
)。

4>    虚基类的支持没有具体的标准,但数据成员存取需要间接完成,有时间的负担。一、按照MS的“virtual
base class table
的方法,需要在object中添加一个该表的指针,通过指针间接存取。二、如果按照“在virtual
function table
中放置offset”只需要计算offset完成数据成员存取。

抱歉!评论已关闭.