重载一个Serialize函数,在这个函数时序列化(串行化)对话框类的每一个子成员变量,就行了,这是microsoft的推荐作法。

解决方案 »

  1.   

    需要吗?直接使用CArchieve类不就行了
      

  2.   

    什么是流式文件储存?简单的说,从当前文件位置,读和写按照完全相同的方式把数据读或写到文件中。
    例如 class A -> file, class B -> file
        file -> class A, file -> class B
    A,B只要按照上面的方式做好自己的流式文件储存就是了。
    这样的优点是:高效,简单
    缺点是:某个数据的位置非常难确定什么叫做序列化?就是某个数据按照 流式文件储存 方式将数据写和读的操作
    具体到VC和这个例子:
    一:没有CArchive类的支持
    Write:
    int n = str.GetLength;
    pFile->Write(&n,sizeof(n));
    pFile->Write((LPCSTR)m_cc.name,n);
    pFile->Write(&m_cc.course,sizeof(m_cc.course));
    pFile->Write(&m_cc.sub,sizeof(m_cc.course));Read:
    int n;
    pFile->Read(&n,sizeof(n))
    if(n > 0)
    pFile->Read(str.GetBufferSetLength(n),n);
    str.ReleaseBuffer(); //这个函数是必须的,我曾经在这里犯了不少错误
    pFile->Read(&m_cc.course,sizeof(m_cc.course));
    pFile->Read(&m_cc.sub,sizeof(m_cc.course));这个结构体的序列花就完成了。如果想要更好的封装,如下:
    struct student
    {
    CString name;
    int course;
    char sub[6];
    CFile & Read( const CFile & File );
    CFile & Write( const CFile & File );
    }abc;
    将上面的代码移到这两个函数里并把 File 返回,则这个类的序列化就完美完成了。
    abc a1,a2,a3;
    a1.Write(file);a2.Write(file);a3.Write(file);
    a1.Read(file);a2.Read(file);a3.Read(file);二:有CArchive类的支持
    这几乎没有什么说的,因为CArchive已经重载了常见数据类型的序列化操作,包括CString,你要做的是:
    写一个Serlize(没有拼写错吧?!)函数,跟CDocument的申明一样,然后
    .....
    {
       if(ar.IsStoring())
       {
           ar << name;
           ar << course;
           for(int i=0;i<6;i++)
              ar << sub[i];
        }
        else
       {
           ar >> name;
           ar >> course;
           for(int i=0;i<6;i++)
              ar >> sub[i];
        }
    }
    外部只需要调用Serlize就可以了。
    进一不,你可以重载操作符 << 和 >>,这样外部的使用更简单了:
    friend CArchive & operator << ( struc & abc, CArchive & ar );
    friend CArchive & operator >> ( struc & abc, CArchive & ar );你可能要问的问题:
    一:不记录或读取CString的长度行不行。
    回答:行,那么,在读取时你只有一个字节一个字节的读取判断是否读完了一个字符串。低效,复杂。
    二:直接将 abc 写或读入行不行。file.Write(&m_cc,sizeof(m_cc));
    回答:不行。这个问题你已经意识到了。为什么?CString里有个指针,写时并不能把字符串内容写入到文件,只是写入了一个指针。读时只是读入了上次的指针内容,并没有把字符串读入,而且继续操作要出问题,因为上次的指针地址不见得这次能用。