注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

多多的爹

 
 
 

日志

 
 

深入解析MFC -- 序列化  

2008-01-23 16:55:07|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

不记得当初为什么会列出这个章节,因为现在看来,MFC的序列化可取之处并不多。
MFC提供了类CArchive来协助数据序列化。对于大部分基本类型来说,都可以通过CArchive的操作符< /><来保存和读取数据。比如:
int a = 4;
ar < a nbspnbspnbsp p>

int b = 0;
ar << b;    // 读数据

值得注意的是,指针并不能被识别,会被错误的识别成bool类型。因此对于指针类型的数据,需要额外写代码支持。函数Read和Write就能大显身手了。
char a[] = "Test";
ar.Write((void*)a, sizeof(a));

对于特殊的类型(即自定义的结构体和类),有三种方式序列化。
第一种是直接将整个对象作为内存块写入和读取,适合于简单的类型,如以下的例子:
struct A
{
    int a;
    short b;
    char[24];
};
A test;
ar.Write((void*)&a, sizeof(A));
这种方式很简单,但很多时候走不通。比如中有指针成员变量或者虚函数的时候,写入和读取都有问题。
第二种方式,实现Serialize函数,在这个函数中做处理数据。序列化时,直接调用此函数。比如想保存CYourView中的数据,重载Serialize函数,在Doc中以下面的方式调用:
void CYourDoc::Serialize(CArchive& ar)
{
    POSITION p = GetFirstViewPosition();
    CYourView* pView = (CYourView*)CDocument::GetNextView(p);
    pView-<Serialize(ar);
}
第三种方式类似前一种。在类的声明定义中加上宏DECLARE_SERIAL/IMPLEMENT_SERIAL(顶替DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE)。同时仍然需要实现Serialize函数。这样在Doc中的调用方式发生了改变:
void CYourDoc::Serialize(CArchive& ar)
{
    POSITION p = GetFirstViewPosition();
    CYourView* pView = (CYourView*)CDocument::GetNextView(p);
    if (ar.IsStoring())
    {
        ar < pView br/>    }
    else
    {
        ar << pView;
    }
}
我并不喜欢第三种方式。因为这样做的结果会导致写入和读取一些额外的数据。展开IMPLEMENT_SERIAL并进入代码,将看到在调用CYourView的Serialize前,会先调用CRuntimeClass的Store或Load。
另外CStringA和CStringW的存储很奇怪,在存储前会根据是否是Unicode写入一些标记,看上去也不太好用。

另外补充一点,展开IMPLEMENT_SERIAL后会发现这样一段代码:
AFX_COMDAT CRuntimeClass CYourView::classCYourView = {
    "CYourView", sizeof(class CYourView), 3, &CYourView::CreateObject, &CYourView::_GetBaseClass, NULL, &_init_CYourView
};
AFX_CLASSINIT _init_CYourView(RUNTIME_CLASS(CYourView));
原来,动态创建的使用方式是这样的,真是恶心的实现啊!

  评论这张
 
阅读(9)| 评论(4)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017