Inside the C++ Object Model chapter 1

1.1.1 简单对象模型
 对象由一系列的slots组成,每个slot中存放着指向对象的一个成员(数据成员与函数成员)的指针,成员按其在类中声明的顺序排序,查找成员等效于查找其在对象中的索引。类对象大小的计算方式:指针大小乘以成员数目(参见书-图1.1)。
 本模型采用空间与执行期效率为代价简化编译器设计复杂度,对象的大小不会因为成员类型的不同而改变――类对象中存储的都是指针。
 本模型关于索引或slot的观念用于实现C++“指向成员的指针”中。
1.1.2 表格驱动对象模型
 在此模型下,为类对象分别建立数据成员表与函数成员表,而类对象本身只含有指向两个表格的指针。数据成员表中存放数据本身(实际数据),而函数成员表中存放的是指向成员函数的指针(参见书-图1.2)。
 本模型关于成员函数表的观念用于virtual function的实现中。
1.1.3 cfront采用的对象模型
 本模型中,static数据成员存放于所有类对象之外,并且只有一份,为所有对象共享;non-static数据成员则置于各个类对象之内;static与non-static成员函数都存放于类对象之外;对于虚函数,则分为两步:
 1. 每个类产生一个存放指针的virtual table(vtbl),其内的指针分别指向类的各个虚函数(一般第一个slot中存放的指针是指向类所关联的类型信息);
 2. 每个类对象添加一个指针vptr,指向与其相关的vtbl(参见书-图1.3)。
本模型优点是具有较好的空间和存取时间的效率,缺点为一旦非静态数据成员有所改变,即使应用程序代码不变,应用程序也得重新编译。
1.1.4 加上继承后的对象模型
 添加继承后的对象模型修改策略:
 1. 指向直接基类的指针模型
 在派生类对象中增加一个slot,其中存放一个指向其直接基类的指针,如果存在多继承,那么相应地增加slot。
 优点为:派生类对象的大小不会因为基类的改变而改变;缺点是:间接性导致额外的空间与存取时间的负担,同时类对象会因为多重继承而增加大小(如图1.1.4-1)。
 2. base table模型
 从派生类开始,在每个类对象内添加一个指向其直接基类的指针bptr,指向其相应建立的基类表base table,而基类表中的每一个slot存放一个指向一个基类地址的指针。
 优点为:派生类对象的大小不会因为基类的改变而改变,同时多继承也不会导致派生类增加额外的空间,这样每个类对象对于继承都有一致的表现方式――一个在固定位置上指向基类表的指针(如图1.1.4-2)。

 从上可以看出,指向直接基类的指针模型与base table模型的差别在于对于继承采用了不同的表现方式:base table采用一致的方式,但它需要更多的空间以及间接存取的时间代价,指向直接基类的指针模型则通过在派生类中增加其继承的基类数目的指针,相对降低了空间与间接存取时间的代价。当然,上述两种策略都存在间接性存取时间的问题――随继承的深度增加而增加。
 3. cfront采用的原始模型
 此模型中,将基类subobject的数据成员直接放置于派生类对象中,这样避免了存取的间接性问题。
缺点是只要基类成员的任何改变,将导致所有用到此基类或其派生类对象的代码重新编译。详细讨论见书3.4节。
 4. cfront支持虚拟基类的模型
 5. cfront支持虚函数(多态)的模型
1.3.3 类对象占用空间的组成部分
 1. non-static数据成员的总大小;
 2. 根据边界对齐需求增设的空间――存放于成员之间或者集合体边界;
 3. 为了支持virtual而由内部产生的任何额外负担,如vptr等。

你可能感兴趣的:(C++,object,function,table,存储,编译器)