重载一个Serialize函数,在这个函数时序列化(串行化)对话框类的每一个子成员变量,就行了,这是microsoft的推荐作法。
解决方案 »
- 如何枚举未受信任的数字证书列表?
- CEdit限制输入字符串长度應該怎樣實現?
- 求教:控件保存为图片
- CStatic控件如何挂载图片和显示提示文字呢?
- 请教高手们,我用了非阻塞的流套接字的异步模式(WSAAsyncSelect),在我用send发大数据的时候,要返回WSANOBUFFER错误,为什么?
- 怪异的问题,我不知道该改程序还是改系统设置了。
- windowsxp vc6.0用ATL建立了一个server的工程作为DCOM,用控制台的程序调用,调不通,系统问题,还是人品问题???
- 这样读取文件有问题吗
- 问
- 怎样通过LAN中的共享计算机名字得到他的IP或MAC地址,操作系统!
- 微软既然能写一个VC编译器,想必反编译器忘不了写一个吧?!
- 这个坛子什么味道??
例如 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里有个指针,写时并不能把字符串内容写入到文件,只是写入了一个指针。读时只是读入了上次的指针内容,并没有把字符串读入,而且继续操作要出问题,因为上次的指针地址不见得这次能用。