现在的位置: 首页 > 综合 > 正文

序列化中CRuntimeClass链表的形成

2013年12月02日 ⁄ 综合 ⁄ 共 2802字 ⁄ 字号 评论关闭

编写可序列化类的步骤

 

1、直接或间接从CObject派生。

2、在类声明中加入DECLARE_SERIAL宏。

3、重载基本类的Serialize函数,并串行化派生类的数据成员。

4、如果派生类没有默认的构造函数,则添加一个。因为对象加载时,MFC要用默认构造函数在浮动标签上创建对象,并用从档案取回的值设置对象数据成员的初始值。

5、在类的实现中写入IMPLEMENT_SERIAL宏。IMPLEMENT_SERIAL宏接收三个参数:类名、父类名和版本号。

 

 

一个示例:

 

宏展开

 

 


CRuntimeClass链表的形成过程。

从上面宏展开可以看出,序列化比动态创建多了一个>>运算符重载,多填写了CRuntimeClass的m_wSchema、m_pClassInit字段。从CRuntimeClass的m_pNextClass字段可以看出,如果要将所有类的CRuntimeClass组成类链表,这个字段也必须填写,但在初始化类的CRuntimeClass中并没有填写这个字段,而是将它置为NULL。

在序列化中,多了一个变量_init_CMyClass,也就是它将类的CRuntimeClass指针加入到了全局链表中。

 

AFX_CLASSINIT是个结构体,它没有成员变量,只有一个包含CRuntimeClass指针参数的构造函数。这个构造函数调用了AfxClassInit()函数,将类的CRuntimeClass初始化到了进程类链表中。  

AfxClassInit()函数首先获得进程模块状态结构Afx_MODULE_STATE,该结构体中的m_classList成员变量即为进程类链表。通过调用m_classList.AddHead(pNewClass),类的CRuntimeClass结构被链接了起来。该链表类仅包含支持序列化的类。

m_classList是CTypedSimpleList<CRuntimeClass*>类型。调用CTypedSimpleList的成员函数AddHead(),将新的CRuntimeClass指针加入了类链表中。

 

CTypedSimpleList调用了父类的CSimpleList::AddHead()。

 

可以看出一个最重要的函数CSimpleList::GetNextPtr(),该函数用来获得指向下一个元素的元素指针。也就是说,CSimpleList存储的结构体元素其中包含一个字段,用于指向链表中下一个元素。

 

m_nNextOffset是CSimpleList的成员变量,它记录了所存储的结构体中,指向下一个元素的元素指针在结构体中的偏移。它是如何被初始化的呢?m_classList是AFX_MODULE_STATE的成员变量。在AFX_MODULE_STATE的构造函数中,有下面这条语句:

 

finished...

 

 

抱歉!评论已关闭.