C++对象模型(1)——关于对象

来源:互联网 发布:网络教育本科怎么报考 编辑:程序博客网 时间:2024/05/21 17:44

 

1.   加上封装之后的成本

C++在布局及存取时间上主要的额外负担是由virtual引起的,包括:

(1)  virtual function机制:

用以支持一个更有效率的“执行期绑定”

(2)  virtual base class机制

用以实现“多次出现于继承体系中的base class 仅有一个单一而被共享的实例”(继承层次中含virtual继承的多继承)

      另外还有就是多重继承带来的负担,发生于“一个派生类与其第二或后继之祖先类之间的转换”

2.c++对象模型

2.1简单对象模型

就是每个对象有一张存储各成员地址的表,每一项是每个成员的首地址,因此一个类的大小很容易被计算出来。而且其所运用的索引概念被c++对象模型所采纳。具体格式如下所示:

 

1   c++简单对象模型

 

2.2表格驱动对象模型

每个对象有含两项成员的一张表,第一项指向存储成员属性的地址块的首地址,第二项指向一张成员函数表,成员函数表每一项指向一个成员函数。其成员函数表的概念被c++对象模型所采用。具体格式如下所示:

 

2   表格驱动对象模型

2.3c++对象模型

静态数据成员与(静态,非静态)函数成员被放在对象之外,非静态成员部署于每个对象内部(存储成员的值),然后每个对象都有一个虚函数表指针指向类的虚表(vtbl)。每个类的vtbl含有两个部分,第一部分即vtbll第一项指向一名叫type_info-object的数据结构(用以支持runtime identification,即RTTI),然后第二部分即从第二项开始每一项指向一虚函数。具体格式如下所示:

3  c++对象模型

 

 

2.4.加上继承

         在虚拟继承下,祖先类不管被继承了多少次,永远只会存在一个实例。那么派生类如何塑造其祖先类那?

       1)简单对象模型中,对象表中存在一项指出基类子对象的地址。

缺点是空间与实间的额外负担;

优点是对象的大小不手机类大小的影响。

       2)表格驱动模型提出了base table,即每个对象有一base table指针指向base table(每一项指向一基类,因为允许多继承,所以使用表格)。

缺点是空间与时间的额外负担;

优点是每个对象都有一致的继承表现方式(base table 指针),无需改变对象本身就可以改变base table

       具体实现如下所示:

 

 

4   继承表形式的实现

 

         3c++采用直接方式,即将基类的数据成员直接拷入子类,缺点是积累成员有任何改变,“基类或子类的对象就必须得重新编译。引入virtual继承机制以后就为虚继承基类关联一virtual base class,或重新添加虚基类表,或扩充虚表。

2.5struct的使用

        1)使用时机

                     传递一复杂class的全部或部分到某函数里时使用

       2)使用条件

                     需保证拥有与c兼容的空间布局,且要保证只在组合情况下才存在

3.对象的差异

3.1 多态的实现

       C++多态只存在于public class体系之中,即只存在于公有继承体系中,非公有继承的多态需要程序员通过显示转换加以支持。

       因而C++提供三种形式支持多态:

(1)   经由隐式转换经派生类指针转化为指向其基类类型的指针:

Derive  *dev=new Base();

(2)   经由virtual function机制:

p->create();

(3)   经由dynamic_casttypeid运算符:

if(Derived  *dev = dynamic_cast<Derived*> (base) )……….]

多态的用途是经由以共同的接口来影响类型的封装,接口通常定义在抽象基类中,这个共享接口是以virtual function机制(可在执行期一句对象的真正类型解析处应该调用那一个函数实例)引发的。

3.2 类对象的实际大小

一个类对象一般包含:

(1)   非静态数据的总大小

(2)   任何由于对齐的需求而填补的空间(可能在成员之间,也可能在集合之间),对其就是将内存大小调整成某数的整数倍,以提高bus的运算效率

(3)   加上为了支持virtual而额外增加的内存空间(virtual functionvirtual base class

所谓的指针的类型是指编译器被告知的寻址的长度(解释内存的内容及内存的大小),而知帧类型的转换也仅仅是改变的解释方式,并不改变指针实际的地址(内存块首地址)

 

 

3.2 加上多态之后

       不管是指针还是引用,都需要一个word的空间,通过隐式转换得到的指向派生类的父类指针是不能访问除了在基类对象出现的成员以外的派生类成员的,除非通过virtual机制调用派生类成员函数,而指向派生类对象的父类指针的类型在编译时期决定以下两点:

       1)固定的可用接口,即指针只能调用公有函数(访问public接口)

       2)该接口的access level(为public

编译器在初始化及指定(assignment,将一个类对象复制给另一个类对象的时候)之间做出了仲裁。

编译器必须确保若某个对象含有一会一个以上的vptrs,则那些vptrs的内容不会被基类对象初始化或改变。

多态所造成的“一个以上类型”的潜在力量并不能够直接发挥在“直接存取object”上。“oo程序设计并不支持对object的直接处理”

一个pointerreference之所以支持多态,是因为他们并不引发内存中任何“与类型有关的内存委托操作”,会受到影响的只是对内存内容与大小的解释方式而已。

多态是一种威力强大的机制,允许继public接口之后封装相关的类型,但要付出额外的代价——额外的间接性(内存的获得或类型的决断)。

 

原创粉丝点击