Persistence(永久保存)机制
 面向对象有一个术语:Persistence,意思是不对象永久保留下来。对象如何能够永久保存?当然是写到文件中去。
 将数据写到文件中是身简单的。Document/View结构中,数据都放在一份document中,只要把其中的成员变量依次写进文件即可/成员变量很可能是一个对象,而面向对象,首先应该记载你类名称,然后才是对象的数据。
 当程序从文件中读到一个类名称时,它如何实现(instantiate)一个对象。这就是动态创建的技术。
 MFC有一套Serialize机制,目的是把文件名的选择,文件的开关,缓冲去的建立、数据的读写、提取运算符(>>)和插入运算符(<<)的重载、对象的动态创建等都包装起来。
 Serialize的各部分工作,除了数据的读写和动态创建外,其余都是枝节。
 
Serialize(数据读写)
假设现有一份文件,用以记录一张图形。图形只有 中基本元素:线条(Stroke)、圆形、矩形。准备用下面的类组织这份文件:
CObject              CRect
 CobList            CPoint
 CDWordArray        CSize
 Cstroke
 Crectangle
 Ccircle
 Cdocument
CmyDoc
其中CObList和CDWordArray是MFC提供的类,前者是一个链表,可放置任何从CObject派生下来的对象,后者是一个数组,每个元素都是double word.另外三个类:Cstroke和Crectangle和Ccircle是我们从CObject派生出来的。
Class CMyDoc : public Cdocument
{
 CObList m_graphList;
 Csize m_sizeDoc;
 
};
Class CStroke : public CObject
{
 CDWordArray m_ptrArray; //series of connected points
 
};
Class CRectangle : public CObject
{
 CRect m_rect;
 
};
Class Cstroke : public CObject
{
 Cpoint m_center;
 UINT m_radius;
 
};
每次记录对象内容室,先写一段代码,表示此对象是否在文件中已经记录过,若是新类记录其类名称;若为旧类,则以代码表示。这样可以节省文件大小和程序用于解析的时间。
 最好每个类都有自己的版本号码,把版本号码记录上去,可以防止旧版和新版程序的互相读取。
 希望有一个专门负责Seralization的函数,叫Serialize若现在的Document类名称为CScribDoc,期望有便利的程序方法:
class CScribDoc:: Serialize (CArchive & ar)
{
 if(ar.IsSorting( ))
    ar<<m_sizeDoc;
 else
    ar>>m_sizeDoc;
 m_graphList.Serialize(ar);
}
class CObList:: Serialize (CArchive & ar)
{
 if(ar.IsSorting( ))
{
    ar<<(WORD)m_nCount;
    for(Cnode *pNode= m_pNodeHead;pNode!=NULL;pNode= pNode->next)
        ar<<pNode->data;
}
else
{
 WORD nNewCount;
 Ar>>nNewCount;
 While(nNewCount){
 CObject *new Data;
 Ar>>newData;
 AddTail(newData);
}
}
];
void Cstroke :: Serialize(CArchive &ar)
{
 m_pterArray.Serialize(ar);
}
void CDWordArray:: Serialize(CArchive &ar)
{
 if(ar.IsSorting())
 {
    ar<<(WORD)m_nSize;
    for(int I=0;I<m_nSize;I++)
        ar<<m_pData[I];
}
else
{
 WORD nOldSize;
 ar>>nOldSize;
 for(int I=0; I<m_nSize;I++)
     ar>>m_pData[I];
}
}
void Crectangle::Serialize(CArchive &ar)
{
 if(ar.IsSorting( ))
    ar>>m_rect;
 else
    ar>>m_rect;
}
void CCircle::Serialize(CArchive &ar)
{
 if(ar.IsSorting( ))
 {
    ar<<(WORD)m_center.x;
ar<<(WORD)m_center.y;
ar<<(WORD)m_radius;
}
else
{
 ar>>(WORD)m_center.x;
ar>>(WORD)m_center.y;
ar>>(WORD)m_radius;
}
}
 每一个可写到文件或可从文件读出的类,都应该有它自己的Serialize函数,负责其自己的数据读写文件操作。此类并且应该改写<<和>>运算符,把数据导流到archive中。Archive是一个与文件息息相关的缓冲区,暂时可以把它想象成文件的化身。
 
DECLARE_SERIAL/IMPLEMENT_SERIAL宏
 >><<两个运算符重载,还要让Serialize函数不知觉地放入类声明中,最好的做法仍然是使用宏。
 类之所以能够进行文件读写操作,前提是拥有动态创建的能力,所以,MFC设计了两个宏DECLARE_SERIALIMPLEMENT_SERIAL:
#define DECLARE_SERIAL(class_name) /
                  DECLARE_DYNCREATE(class_name) /
                   Friend Crichive & AFXAPI operator>>(Carichive & ar,class_name * &pObj);
#define IMPLEMENT_SERIAL(class_name,base_class_name,wSchema) /
                  CObject *PASCAL class_name::CreateObject() /
                  { return new class_name;} /
                  _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,/
class_name::CreateObject ) /
                  CArchive & APXAPI operator >> (CArchive &ar,class_name * &pOb) /
                   {
                            pOb=(class_name *)ar.ReadObject(RUNTIME_CLASS(class_name));/
                            return ar;
}/
 为了在每一个对象被处理(读或写)之前,能够处理琐屑的工作,诸如判断是否是第一次出现,记录版本号码,记录文件名等工作,CRuntimeClass需要两个函数LoadStore:
Struct CRuntimeClass
{
 //Attributes
    LRCSTR m_lpnzClassName;
    Int m_nObjectSize;
UINT m_wSchema; //schema number of the loaded class
CObject *(PASCAL * m_pfnCreateObject)();//NULL=>abstract class
CRuntimeClass *m_pBaseClass;
CObject * CreateObject();
Void Store(CArchive & ar) const
Static Cruntime * PASCAL Load(CArchive &ar,UINT * pwsSchemaNum);
//CruntimeClass objects linked together in the simple list
static CRuntimeClass *pFirstClass;
CRuntimeClass * m_pNextClass;
}
 Load函数是从文件中读一个类名称,Store函数是把类名称写入文件中:
CRuntimeClass * PASACL CRuntimeClass::Load(CArchive &ar,UINT *pwSchemaNum)
{
WORD nLen;
Char szClassName[64];
CRuntimeClass *pClass;
Ar>>(WORD &)(*pwSchemaNum)>>nLen;
If(nLen>=sizeof(szClassName)||ar.Read(szClassName,nLen)!=nLen)
 Return NULL;
SzClassName[nLen]=/0;
For(pClass=pFirstClassName;pClass!=NULL;pClass=pClass->m_pNextClass)
{
 if(Istrcmp(szClassName,pCLass->m_lpszClassName)==0)
 return pClass;
}
return NULL;
}
void CRuntimeClass::Store(CArchive &ar)const
{
    WORD nLen=(WORD)lstrlenA(m_lpszClassName);
    ar<<(WORD)m_wSchema<<nLen;
    ar.Write(m_lpszClassName,nLen*sizeof(char));
}
 为了让整个Serialization机制运行起来,必须做这样的类声明:
class CScribDoc : public CDocument
{
         DECLARE_DYNCREATE(CScribDoc )
         …
};
class CStroke : public CObject
{
         DECLARE_SERIAL(CStroke)
Public:
         Void serialize(Carichive &);
         …
};
class CRectangle : public CObject
{
         DECLARE_SERIAL(CRectangle)
Public:
     Void Serialize(CArchive &);
};
class CCirecle : public CObject
{
         DECLARE_SERIAL(CCirecle)
Public:
     Void Serialize(CArchive &);
};
在执行文件(.cpp)中进行如下的操作:
IMPLEMENT_DYNCREATE( CScribDoc,CDocument )
IMPLEMENT_SERIAL( CStroke,CObject ,2 )
IMPLEMENT_ SERIAL ( CRectangle, CObject,1 )
IMPLEMENT_ SERIAL ( CCircle, CObject ,1 )
 

MFC深入浅出--永久保存相关推荐

  1. MFC六大核心机制之四:永久保存(串行化)

    永久保存(串行化)是MFC的重要内容,可以用一句简明直白的话来形容其重要性:弄懂它以后,你就越来越像个程序员了! 如果我们的程序不需要永久保存,那几乎可以肯定是一个小玩儿.那怕我们的记事本.画图等小程 ...

  2. Windows Phone 8初学者开发—第21部分:永久保存Wav音频文件

    第21部分:永久保存Wav音频文件 原文地址:http://channel9.msdn.com/Series/Windows-Phone-8-Development-for-Absolute-Begi ...

  3. linux怎么永久保存,Linux系统中,让alias命令永久保存的方法!

    Background 最近接触到了Linux系统,在学习的过程中有一个命令别名我感觉特别有意思.于是我照着教程编写了我自己的命令alias zzm='echo "wlz, I love u& ...

  4. git永久保存账号密码

    在git bash 中执行命令: git config --global credential.helper store 在输入一次账号密码就可以永久保存了,免去git重复输入账号密码操作

  5. ubuntu服务器修改保存文件,Ubuntu Server 如何永久保存iptables的设置?

    iptables是Linux操作系统常用的netfilter防火墙规则的管理指令.对于刚接触iptables的用户来说,经常会不知道该如何把用iptables设置好的防火墙规则进行「存盘」,让它在下次 ...

  6. Android Studio数据永久保存——SharedPreferences

    数据永久保存--SharedPreferences 关于数据存储: 关于SharenPreferences 外部类访问SharedPreferences的数据的操作: 小结 本文为学习类文档,通过学习 ...

  7. Centos 7 环境下将修改后的MAC地址永久保存

    Centos 7 环境下将修改后的MAC地址永久保存的正确的步骤如下: #ifconfig eth0 down #vim /etc/sysconfig/network-scripts/ifcfg-et ...

  8. MAC OS ssh key永久保存

    MAC OS 的新版本中不能再像原来一样通过:ssh-add -K 来将密钥或是密钥的密码永久保存,这样每次重启后你将不得不再加载一遍密钥或是输入一遍密码,网上查了几种方法如automator等都不太 ...

  9. 有道云笔记怎样与微信连接服务器,有道云笔记打通微信接口 文章永久保存多终端查看...

    近日,有道云笔记与微信达成合作,打通微信的收藏接口,微信中的文章.对话和图片,可一键导出到有道云笔记中,并永久保存.用户可以在不同平台,随时查看.编辑和管理从微信中保存的珍贵内容. 使用有道云笔记&q ...

  10. 手机里隐藏了一个无限空间,可以永久保存照片视频,好多人不知道

    很多人都试过手机内存不够了,要清理一下相片或视频,但是选来选去我都不想删掉都很喜欢啊,该怎么办呢?没关系,今天我们来分享一个手机可以免费永久保存照片视频的方法,而且空间是无限制的,你想存多少都可以.不 ...

最新文章

  1. python利用requests进行爬虫_Python利用Requests库写爬虫(一)
  2. 算法题:输入一个表示整数的字符串,把该字符串转换成整数并输出。例如输入字符串“12345”,则输出整数“12345”
  3. 程序员未来的职业生涯路该怎么走,如何避免35岁中年危机?
  4. JVM学习笔记(二):垃圾收集
  5. jinfo java_Java自带的JVM性能监控及调优工具(jps、jinfo、jstat、jmap、javap)使用介...
  6. 部署KVM虚拟化(单网桥与多网桥VLAN模式)
  7. 【比赛】CCL“中国法研杯”相似案例匹配评测竞赛 - TOP队伍攻略分享
  8. 资源 | 邓力、刘洋等合著的这本NLP经典书籍之情感分析中文版
  9. 自学c语言每天一小时,昨天学习C语言第五天, 自学失败的一天
  10. 特洛伊木马程序_为什么物联网设备是我们这个时代的特洛伊木马?为什么没人谈论它?...
  11. python vscode下载和安装教程(windows)
  12. 计算机处理答题卡原理,中高考答题卡扫描进电脑原来是这样的!难怪要被多扣分了(附卷面高分八法)...
  13. Python数据分析通关,30个案例!
  14. 护理自考本科科目计算机应用基础,护理自考本科考哪些科目
  15. CSDN好的blog
  16. pycharm前进、后退快捷键
  17. Generalized Focal Loss
  18. 如何在家利用网络副业赚钱,这三个网上副业,做好比主业更好
  19. 古魂魂之刃2电脑版用逍遥模拟器电脑上玩手机账号数据互通
  20. HCL模拟器的使用心得

热门文章

  1. 唐人街徒步:在异国情调的纽约感受浓厚的中式气息
  2. 春节宅家玩什么?8款小游戏陪你一起过年
  3. 养花追美女的java游戏,小米有品上架懒人鱼缸:上面养花 下面养鱼
  4. 企业思想家:专家详解元宇宙逻辑和产业机会 (5000余字)
  5. web 页面实现页面右下角弹窗功能
  6. 【小程序按钮控制视频播放暂停】
  7. Latex自定义图表序号
  8. VS2019下载(离线下载器)
  9. linux执行arm文件,Linux安装FFMPEG转换amr为mp3格式
  10. JAVA编程语言基础第六章