Inside The C++ Object Model(三)Data语意学

来源:互联网 发布:电脑k歌软件 编辑:程序博客网 时间:2024/05/16 08:41

一 引导:

(1)类对象的大小和机器、编译器有关。

(2)类对象的大小受到三个因素的影响(除了对象所有的nonstatic data members):

1.语言本身的所造成的额外负担。例如:支持virtual base class时就会导致额外负担。

2.编译器对于特殊情况所提供的优化处理。

3.Alignment的限制。在32机器上通常alignment通常为4字节。


二 Data Member的绑定。

三 Data Member的布局:C++ Standard允许编译器决定布局,所以不同编译器不同。

四 Data Member的存取:

(一)static data member:(直接通过类存取,也可通过对象存取)

(1)static data members可被视为global 变量(但作用域在类中)。

(2)每个static data member只有一个实体,存放在程序的data segment中,每次取用static member,就会被内部转换为对唯一的extern实体的直接操作。从指令的执行观点来看,这是C++中"通过一个指针和通过一个对象来存取member,结论完全相同的"唯一一种情况。

(3)取一个static data member的地址,会得到一个指向其数据类型的指针,而不是一个指向其class member的指针,因为static member并不内涵在一个class object之中。

(4)如果两个class声明同名的static member会导致名称冲突,编译器的做法是暗中对每个static data member编码(name),以获得一个独一无二的程序识别代码。

(二)nonstatic data  member:

(1)对一个nonstatic data member的存取操作,编译器需要把class object的起始地址加上data member的偏移量,每一个nonstatic data member的偏移量在编译期即可知道。


五 继承与Data Member:

(一)单一继承没有多态。

(二)单一继承+多态:

1.多态的负担:

*导入一个与类相关的virtual table存放它声明的每一个virtual function。

*每一个类对象都导入一个vptr,提供执行期的链接,使每一个object能够找到相应的virtual table。

*加强constructor,使它能够为vptr设定初值,让它指向class对应的virtual table。

*加强destructor,使它能够撤销"指向class相关virtual table"的vptr。

2.vptr的放置位置:

*通常把vptr放置在base class的尾端。

(三)多重继承:

1.对于一个多重派生对象,将其地址指定给“最左端(即第一个)”base class的指针,情况和单一继承一样,因为两者都指向相同的起始地址。

2.对于第二个或后继的base class的地址指定操作,需将地址修改,加上或减去介于中间的base subobjects大小。

3.编译器通常根据派生列表中的声明次序来排列基类。

4.如图:



(四)虚拟继承:


1.Microsoft编译器:class如果有一个或多个virtual base classes,就会由器安插一个指针,指向virtual base class table。

*如下图:


2.GCC:在virtual function table中放置virtual base classes的offset。


六 对象成员的效率

七 指向Data Members的指针:

1.取一个nonstatic data member的地址,将会得到它在class中的offset。(例如:&base::a;待验证)

2.取一个绑定于真正class object身上的class member的地址,将会得到该member在内存中的地址。