MFC的序列化的一点研究.
最近“下岗”在家,前一段时间一直在研究MFC的源代码,觉得越是深入越是有意思,特别是最近一周对MFC中对于序列化的支持,总算是研究明白它的整个实现过程,对于序列化的一点分析见解如下,如有不正确的地方,还请多多指教。
序列化主要涉及到一个是写入磁盘,一个是如何从磁盘中读出数据,特别是如何写入一个Object,下面以一个例子来说明过程.
class CMyObject:public CObject {
public:
DECLARE_SERIAL()
void Serialize(CArchive& ar);
int m_nFoo;
CString m_strFoo;
}
首先我们的一个类派生自CObject,并有了动态创建的功能,还有一些其它的额外的好处了,我们这里要重写Serialize这个虚函数,在这个函数中我们写我们自己的序列化代码,我们可以存入类成员变量....
在实现的地方我们加上:
IMPLEMENT_SERIAL( CMyObject,CObject,1)
void CMyObject::Seralize(CArchive& ar) {
//如果是写入
if ( ar.IsStoring()) {
ar<<m_nFoo;
ar<<m_strFoo;
} else {
ar>>m_nFoo;
ar>>m_strFoo;
}
}
这个过程涉及的代码比较多,我在这里不把代码列出,只说一下大概的过程,大家如果有兴趣看看这几个文件: filecore.cpp ,arccore.cpp,arcobj.cpp, afx.h
1.当我们进行写盘的时候,比如:
CMyObject obj;
ar.WriteObject(&obj);
如果首次写入该类的实例的话,它写入一些关于类的信息,包括类标识,Schema,类名长度,以及类名,注意这个类名以后用于读出的时候再生对象时候用的,然后再调用我们写的序列化代码,写入实际的数据。以后再写入此类的数据时,并不再写入此类的完整信息,而只是此类的CRuntimeClass的地址在CArchive的内部维护的一个CMapPtrToPtr中的index与一个常量的位与,这个也用于以后再读入时用的。还有一种写入的情况就是同样的一个地址的变量写入不止一次的时候,除了第一次写入,以后只是写入一个以前的写入的一个对象的一个下标....
内容较多,下次再写吧!