C小加

厚德 博学 求真 至善 The bright moon and breeze
posts - 145, comments - 195, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

MFC文档序列化实现保存和加载

Posted on 2013-03-02 18:04 C小加 阅读(7896) 评论(2)  编辑 收藏 引用 所属分类: VC++

1、序列化定义

MFC文档-视图结构中,序列化机制可以实现内存中对象储存和加载。

序列化机制分为序列化和反序列化,序列化是把内存中的对象以二进制文件的形式存储在磁盘中。反序列化是把序列化后生成的文件恢复到内存。

2CArchive

CArchive没有基类。
CArchive允许以一个永久二进制(通常为磁盘存储)的形式保存一个对象的复杂网络,它可以在对象被删除时,还能永久保存。可以从永久存储中装载对象,在内存中重新构造它们。使得数据永久保留的过程就叫作序列化”
可以把一个归档对象看作一种二进制流。象输入/输出流一样,归档与文件有关并允许写缓冲区以及从硬盘读出或读入数据。输入/输出流处理一系列ASCII字符,但是归档文件以一种有效率、精练的格式处理二进制对象。

3CArchive对象处理基础类型数据


必须在创建一个CArchive对象之前,创建一个CFile对象。另外,必须确信归档文件的装入/存储与文件的打开模式是兼容的。每一个文件只限于一个活动归档文件。
当构造一个CArchive对象时,要把它附加给表示一个打开文件的类CFile(或派生类)的对象上。还要指定归档文件将用于装载还是存储。

示例:

CFile file("1.txt",CFile::modeCreate | CFile::modeWrite); //定义一个文件流对象
 CArchive ar(&file,CArchive::store);  //定义一个序列化对象和文件流对象绑定并指定归档方式为储存,加载的方式为CArchive::load
 int i=4;
 
char ch='a';
 
float f=1.3f;
 CString str(
"aa");
 ar
<<i<<ch<<f<<str; //储存到文件


4CArchive对象处理自定义对象类型数据


CArchive对象不仅可以处理首要类型,而且还能处理为序列化而设计的特殊的类的对象。可以序列化的类有以下特点:

1、必须为CObject派生类。直接或者间接的继承CObject类。

2、必须重写CObject类的Serialize成员函数。

3使用DECLARE_SERIALIMPLEMENT_SERIAL宏。

4、必须有一个默认构造函数

在Serialize成员函数中完成保存和加载的功能。

DECLARE_SERIAL( class_name ) 参数为当前类名。

IMPLEMENT_SERIAL( class_name, base_class_name, wSchema ) 第一个参数为当前类名,第二个参数为父类类名,第三个参数为该类的特定整型标识,该标识将用来解序(重新实例化),最小为0

示例:

//DrawBase.h
class CDrawBase : public CObject //继承自CObject
{
public:
    DECLARE_SERIAL(CDrawBase)    
//第一个宏的位置,参数为当前类名
    CDrawBase();//必须有一个默认构造函数
    virtual void onDraw(CDC* pdc);
    
virtual ~CDrawBase();
public:
    UINT m_PenStyle;
    
int m_PenWidth;
    
int m_BkMode;
    
int m_BrushStyle;
    
int m_issx;
    
int m_isyy;
    COLORREF m_PenColor;
    COLORREF m_BackgroundColor;
    COLORREF m_BrushColor;
    CPoint m_ptBegin;
    CPoint m_ptEnd;
public:
    
void Serialize(CArchive& ar);//重写了Serialize成员函数
}
;

//DrawBase.cpp
IMPLEMENT_SERIAL(CDrawBase, CObject, 1//第二个宏的位置,第一个参数为当前类名,第二个参数为父类类名,第三个参数为该类的特定整型标识,该标识将用来解序(重新实例化),最小为0
void CDrawBase::Serialize(CArchive& ar)
{
    CObject::Serialize(ar);
    
if(ar.IsStoring())//保存,加载为ar.IsLoading()
    {
        ar 
<<m_PenColor<<m_PenStyle<<m_PenWidth<<m_BrushColor<<m_BrushStyle<<m_issx<<m_isyy;
    }

    Else 
//加载
    {
        ar 
>>m_PenColor>>m_PenStyle>>m_PenWidth>>m_BrushColor>>m_BrushStyle>>m_issx>>m_isyy;
    }

}

重载提取(>>)和插入(<<)是方便的归档编程接口。它支持主要类型和CObject派生类。
CArchive还支持使用MFC Windows套接字类CSocketCSocketFile编程。IsBufferEmpty成员函数也支持这种使用。

一些集合类也支持序列化,CObArray,Vector,CPtrArray

MFC文档-视图结构中,Doc类是被系统设定好支持序列化的类,在Doc类中重写Serialize成员函数。在函数中对你要保存的对象序列化。

完成之后,点击菜单栏上的保存和打开就可以实现序列化了。

 




Feedback

# re: MFC文档序列化实现保存和加载   回复  更多评论   

2013-03-06 07:23 by http://getbestessays.com/
Very ncie greston i cegreat!
完成之后,点击菜单栏上的保存和打开就可以实现序列化了。

# re: MFC文档序列化实现保存和加载   回复  更多评论   

2013-03-07 13:06 by hadoopdev
文章写的不错,可以作为MFC入门者的参考教材。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理