CObject 支持持续性和动态性的宏

来源:互联网 发布:淘宝网9.9包邮 编辑:程序博客网 时间:2024/05/22 14:29

从CObject类直接或间接派生的类,虽然支持持续性和动态性,但是这种支持是有限的。另外还有三
对宏用来弥补上述缺陷。以CStudent类为例。
1. DECLARE_DYNAMIC和IMPLMENT_DYNAMIC
第一对宏支持动态性服务,主要支持IsKindOf服务,告知该类以及基类的类名及大小,得到该类及其
基类的CRunTimeClass结构信息。
2. DECLARE_DYNCREATE和IMPLMENT_DYNCREATE
第二对宏是在第一对宏的动态性服务的基础上,提供了对对象的动态创建的支持。在类中又增加了一
个CreateObject()函数,返回动态创建的该类对象。
3. DECLARE_SERIAL和IMPLMENT_SERIAL
第三对宏的作用是提供对象的持续性,它在第二对宏的基础上,增加了支持使用>>操作符以重建该
类对象的能力,下面以CStudent类为例,在该类加入一对DECLARE_SERIAL和IMPLMENT_SERIAL
宏,使CStudent具有对象持续能力。
综上所述,三对宏对CObject派生类的支持程序表示为不同的层次,在类的定义中使用不同的
宏,可以使类获得不同层次的动态性和持续性的支持。我们通常需要使用一个或多个从CObject类派
生的类对象来组成一个文档对象内的复杂的数据,这样的派生类需要第三对类的支持,即获得对象的
持续性支持。

文档序列化原理
已知文档类的数据的保存和读取,是通过文档类的虚函数Serialize()函数来进行的,其参数CArchive对象ar是指向要操作
的文件的档案类对象。但是对于应用程序框架来说,CArchive对象ar是怎么得到的?什么时候调用Serialize()函数?文档
类中什么类型的数据可以借助Searialize机制完成文档的序列化?这是本节要讨论的问题。
从程序清单8-16中给出了一个Serialize()函数的基本形式。由于CArchive对象ar保存了打开文件的信息以及读或写等方
面的信息,当往文件中写数据时,执行ar.IsStoring()分支,操作运算符<<能把数据存到ar指定的文件中去;当从文件读
取数据时,则执行另一分支,操作运算符>>能从文件读数据,并初始化相关成员变量。
Serialize函数的参数ar是一个CArchive类型的对象,它包含一个CFile类型的文件指针。CArchive对象为读写CFile对象
中的可串行化数据提供了一种类型安全的缓冲机制。通常CFile代表一个磁盘文件;但它也可以是一个内存文件
(CMemFile对象)或剪贴板。一个给定的CArchive对象只能读数据或写数据,而不能同时读写数据。当保存数据到
CArchive对象中时,CArchive把它放在一个缓冲区中。直至缓冲区满,才把数据写入它所包含的文件指针指向的CFile对
象中。同样的,当从CArchive对象读数据时,CArchive对象从文件中读取到缓冲区,然后再从缓冲区读入到可串行化的
对象中。这种缓冲机制减少了访问物理大生产的次数,从而提高了应用程序的性能。在应用程序框架中,ar对象是由应用
程序框架来完成初始化的。
当选择菜单命令File->New时,应用程序框架调用OnNewDocument()函数建立新的文档。OnNewDocument()函数将
首先调用DeleteContents()清空文档类数据成员,然后,再调用SetModifiedFlag(FALSE)将文档修改标志清除。
当选择菜单命令File->Open时,应用程序框架调用OnOpenDocument()函数打开已有的文档。OnOpenDocument()
函数将首先调用GetFile()函数获得给定文件的CFile指针,再调用DeleteContents()函数清空文档类的数据成员,然后把
CFile指针构造 CArchive对象交给Serialize()函数完成读文件重建文档对象的工作,将调用SetModifiedFlag(FALSE)将文
档修改标志清除。
当选择菜单命令File->Save或者File->Save AS时,应用程序框架将调用OnSaveDocument()函数保存指定文件名的文
档。OnSaveDocument()将首先询问文件的名字,调用GetFile()函数获得给定文件的CFile指针,然后把CFile指针构造的
CArchive对象交给Serialize()函数完成写文件的工作,将调用SetModifiedFlag(FALSE)将文档修改标志清除。