对象I/O技术的模拟实现

时间:2022-09-23 06:09:12

对象I/O技术的模拟实现

摘要:C++对象是存活于内存中的,但是由于RAM的易失性,需要将存活于内存中的对象,通过I/O技术及时地交换到外存中,以保证对象的持久存在(对象I/O技术也称为对象的持久化,即Persistence), 所以对象I/O技术也成了C++中的一个重要操作。对象I/O技术的实现需要为对象增加一些额外的运行时信息,即RTTI,技术上的复杂性增加了开发人员所理解对象I/O的难度。本文通过对一个对象I/O技术的模拟实现,深入探讨了对象I/O技术的实现机制。

Abstract: C++ object is alive in the memory, but because of RAM volatile, you need to timely switch the survive object in the memory through I/O technology to the external memory in order to ensure the object persistence (object I/O technology is also referred to as object persistence, that is, Persistence), so the object I/O technology has become an important operation in C++. The realization of Object I/O technology needs to add some additional run-time information, that is, RTTI; technical complexity increased the object I/O difficulties developer understand. In this paper, through object I/O technique simulation, the object I/O technology implementation mechanism is deep discussed.

关键词:RTTI;对象I/O;对象持久化

Keywords: RTTI;object I/O;object persistence

中图分类号:TP311文献标识码:A文章编号:1006-4311(2010)09-0019-02

0引言

我们知道C++对象是“存活”在RAM中的,由于RAM的易失性[1],程序需要将对象存入磁盘中,将来需要时再把对象读入内存加以恢复,这样一来就好像对象一直“活”着一样,因此对象的持久化是C++中的一个非常重要的操作。

许多程序员可能有这样的误区,利用下面的代码:saveClassName( );className=readClassName( ); p=new className;不就轻松实现对象的保存和恢复了吗?

需要指出的是,在C++中,是通过new A而非new “A”(或className =“A”,new className)实例化A的对象。换句话说,试图利用下面的代码className=readClassName( ); p = new className;来达到通过类的字符串名称动态创建对象的做法是根本行不通的,因为p = new className根本无法通过编译![2]

由此我们得出对象的持久化需要的两个条件:

①获取对象所属类的名称的能力;

②能根据类的字符串名字动态创建对象的能力。

这两种能力的获得目前有两种解决方案:

一是由C++编译器(compiler)提供――例如Borland C++ 4.5:二是由程序员自己加上去。

本文是通过第二种方法模拟实现对象的持久化机制,从而深入探讨了对象I/O技术的实现机制。

本文结构如下,首先描述了对象持久化的实现,其次对实现进行了验证,最后是论文进行总结。

1对象持久化的实现

为了说明问题而又不失一般性,我们假定有三个类,分别是Object, A和B,其中A和B都派生于Object,类的定义如下:

为了让对象具备持久化的两个条件,需要依次为对象添加如下信息。

1.1 为每个类增加对象创建函数CreatObject,如表2所示。

1.2 增加类的识别信息(类名称或ID等)以及继承信息,由于这部分信息比较多,可以将其整合到一个结构体Struct ClassInfo中。ClassInfo中保存有两个链表:类的继承链表和程序中所有类的类型信息链表。类的识别能力就由这两个链表来完成。换句话说,我们希望在main函数执行之前内存中就存在如图1所示的两个链表。其中类的继承链表是由Struct ClassInfo的带参构造函数完成的(在VC++中,结构体也可以有构造函数),而类的类型信息链表则是由ClassInfoInit类完成的。Struct ClassInfo和ClassInfoInit的定义如表3所示。注意,链表的创建是在它们的构造函数中完成的。

最后一步,将类型信息作为类的静态的成员变量添加进来,并为每个类实例化静态的初始化类,目的是在main函数执行之前得到图1所示的两个链表。

在这要强调一下static关键字的作用:

①如果类的成员变量被Static关键字所修饰,则这该属性不是为类中的每个对象分别拥有,而是共用,其引用形式不是对象成员变量,而是类成员变量,即不需要市里实例化对象就可以使用。成员函数也与此相仿[3]。

②如果对象(包括作为类成员的对象),如initObject 、ObjectInfo等,被说明为Static,则这些对象是在main函数执行之前就已经存在了,换句话说,这些对象的构造函数是在main函数调用之前就已经被调用了。因此在main函数执行之前,内存中就已经存在着图1所示的链表就可以理解了。

我们添加的RTTI信息能否有效的支持对象的持久化可以由试验来验证。

2试验

该试验主要验证了对象持久化必须具备的两个能力,即动态创建对象能力和获取对象所属类的能力。试验的环境如下:操作系统Windows XP sp2,IDE环境是VC++6.0 SP6。如需要全部源代码可与作者联系()。

通过对象增加的RTTI信息(增加的静态成员变量),获取对象所属类的能力自然具备。

动态创建对象能力实际上就是根据类的字符串名称来实例化对象的能力,在图1所示链表的支持下,该功能可以非常轻松的实现。

思路如下:通过ClassInfo :: pFirstClass查找类名匹配的ClassInfo,利用ClassInfo中的pCreateObject指针实例化对象,为方便起见,可为程序增加查找函数

lookup

ClassInfo * lookup(string name)

{

ClassInfo * p1;

p1=ClassInfo::pFirstClass;

for(;p1!=NULL;p1=p1->nextClass)

{

if(p1->name==name) return p1;

}

return (ClassInfo *)NULL;

}

main()

{

obj * p1

string name;

cin>>name;

if(p1=lookup(name))

p1->pCreateObject();

else

cout

3结束语

本文在手动添加的RTTI信息的支持下实现了对象的持久化,从中读者可以深入了解对象持久化的的实现机制。

在商业的编译器VC++中其实现持久化是通过一个神秘的宏,当将该宏展开后,VC++实现持久化的的思路和本文大同小异,只是更精巧[4]。

参考文献:

[1]Stanley B.Lippman.Inside The C++ Object Model (深度探索C++对象模型)[M].侯捷,译.武汉:华中科技大学出版社,2001.

[2]葛磊.The Object's Permanence Technology and Its Realization in MFC[J].开封大学学报,2006,20(1).

[3]钱能.C++程序设计教程[M].第二版.北京:清华大学出版社,2005:418-419.

[4]侯捷.深入浅出MFC[M].武汉:华中科技大学出版社.

上一篇:刍议企业管理会计工作的精细化 下一篇:对无线网络数据安全的思考