总的来说,序列化作用是把MFC中的所有对象都存储到硬盘上(storing)或者从硬盘上的数据创建相应的对象(loading)。
Serialization的逻辑结构:
要是一个类能够序列化,则该类须直接或间接派生自CObject并且要包含宏DECLARE_SERIAL(在类的Declaration中)和IMPLEMENT_SERIAL(在类的Implement中)。
 
Serial函数
 
假设类CStudent的声明中有如下代码:
public:
    CString m_strName;
    int     m_nGrade;
它的Serial函数也许就是:
void CStudent::Serialize(CArchive& ar)
{
    TRACE("Entering CStudent::Serialize\n");
    if (ar.IsStoring()) {
        ar << m_strName << m_nGrade;
    }
    else {
        ar >> m_strName >> m_nGrade;
    }
}
IsStoring函数用来判断是在Storing还是在Loading。“<<”是Insertion运算符,使用值参数;“>>”是extraction运算符,使用引用参数。
如果CStudent派生自CPerson(或者其他),则还要调用CPerson::Seralize。但无需调用CObject::Serialize,因为它什么东西都不做。
 
Loading Embeded Objects and Pointers
 
Embeded Objects
比如在上述在CStudent声明中又有:
public:
    CTranscript m_transcript;
则它的Serialize函数应为:
void CStudent::Serialize(CArchive& ar)
{
    if (ar.IsStoring()) {
        ar << m_strName << m_nGrade;
    }
    else {
        ar >> m_strName >> m_nGrade;
    }
    m_transcript.Serialize(ar);
}
也就是说直接调用Embeded Objects的Serialize函数。
 
Embeded Pointers
序列化Embeded Pointers有两种方法。
可以先先New一个对象指针赋给Embeded Pointers,然后调用Serialize函数
例如:
在CStudent声明中有:
public:
    CTranscript* m_pTranscript;
Serialize函数可以为:
void CStudent::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
        ar << m_strName << m_nGrade;
    else {
        m_pTranscript = new CTranscript;
        ar >> m_strName >> m_nGrade;
    }
    m_pTranscript->Serialize(ar);
}
第二种方法是:
void CStudent::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
        ar << m_strName << m_nGrade << m_pTranscript;
    else
        ar >> m_strName >> m_nGrade >> m_pTranscript;
}

序列化Collections
如果调用序列化例如CStudent的CObList Collection,那么每个CStudent的Serialize函数将依次被调用。
关于Loading Collection的一些细节:
1、如果Collection包含着不同类的指针,那么每个类的名字将被存储以便被创建;
2、如果一个对象里面包含一个Collection,那么在调用Serialize之前须清空Collection。如在Document中调用DeleteContents。
3、从Archive中load一个Collection有以下步骤:
      a、识别对象的类名;
      b、在堆中给对象分配空间;
      c、把对象的数据存入分配的空间中;
      d、把指向新对象的指针存入Collection中。