⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 13.3 文档文档串行化.txt

📁 网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读
💻 TXT
字号:
13.3 文档文档串行化 
13.3.1 文档类的 Serialize函数
读者可以看到 CGraphicDoc类有一个 Serialize函数,该函数原始定义代码如例 13-10所示。可以
看到,该函数有一个参数,类型是 CArchive引用类型。
例 13-10 

void CGraphicDoc::Serialize(CArchive& ar) 
if (ar.isStoring () ) 
// TODO: add storing code here 
else 
// TODO: add loading code here 

在此函数中,首先判断 CArchive对象 ar的当前状态,如果是存储状态,则在其后增加相应的存储
代码。否则在 else子块中增加加载数据的代码。
我们首先将先前为 Graphic程序设置的断点全部移除,然后在如例 13-10所示 Serialize函数处设
置一个断点,调试运行Graphic程序。选择【文件飞保存】菜单项,输入文件名,单击【保存】按钮,
将可以看到程序进入到这个 Serialize函数。继续运行程序,然后单击【文件飞打开】菜单项,选
择另外一个文件,单击【打开】按钮,会发现程序又进入到这个 Serialize函数。实际上,这个 
Serialize函数就是文档类提供的用来保存和加载数据的函数,我们就可以利用其参数提供的 
CArchive对象来保存或加载我们自己的数据。
下面,我们通过一个简单的例子利用 CGraphicDoc类的 Serialize函数实现数据的保存和加载。首
先在如例 13-10所示 Serialize函数的 if子句块中添加如例 13-11所示代码。 
例 13-11 

int i=5; 
char ch=' b' ; 
float f =1 .2f; 
CString str(''http://www.sunxin.org''); 
ar<<i<<ch<<f<<str; 

上述例 13-11所示代码定义了一个整型变量(i)、一个字符变量 (ch)、一个浮点变量
(f)和一个 CString类型的变量 (sω,井为它们赋了相应的值,然后利用 CArchive类重载的插入操
作符(<<)保存这些数据。
然后,我们在上述例 13-10所示 Serialize函数的 else子句块中添加如例 13-12所示的代码。 
例 13-12 

inti; 
char ch; 
float f; 
CString str; 
CString strResult; 
ar>>i>>ch>>f>>str; 

strResult.Format("毡 d,毡 c,毡 f, %s", i, ch, f, str); 

AfxMessageBox(strResult) ; 
上述如例 13-12所示代码定义了一个整型变量 (0、一个字符变量 (ch)、一个浮点变量(f)和一个 CS
位ing类型的变量 (s位),分别用来保存加载后的数据。并且还额外定义了一个 CString类型的对象 
(strResult),用来保存对加载后得到的数据进行格式化后的字符串。然后,利用 CArchive重载的
加载操作符(>>)加载数据。→定要注意保存和读取数据的顺序。最后,利用 AfxMessageBox函数显
示加载得到的数据。
运行 Graphic程序,选择【文件飞保存】菜单项,使用默认的保存文件名Graphic.txt,单击【保存】
按钮,然后我们在该程序所在目录下可以看到 Graphic.txt文件。接着在不关闭 Graphic程序的情
况下,单击【文件飞打开】菜单项,选择 Graphic.txt文件,单击【打开】按钮,程序并没有如我
们希望的那样出现显示读取结果的消息框。为了找到问题的原因,
我们在CGrapbicDoc类的Serialize函数开始处,以及else子句块中分别设置一个断点,然后调试运
行Graphic程序,选择【文件\保存】菜单项,程序将弹出"保存为"对话框,选择Graphic.txt文件作
为保存目标文件,然后发现程序进入到CGraphicDoc类的Serialize函数内,并且判断出当前缸对象
的状态是保存,于是通过CArchive对象将数据保存到文件中:接着当打开【文件\打开】菜单项时,
程序弹出"文件打开"对话框,选择Graphic.txt文件打开,但是将发现程序没有进入到CGraphicDoc
类的Seriaiize函数中,这是为什么呢?我们来分析一下程序运行过程,当保存数据时,先前创建的
文档类的对象就与该数据关联在一起了,表示了该数据。当再次打开刚保存的文件时,在 MFC框架
内部,它判断出这是同一份数据,并且和这个数据相关联的文档类对象的指针已经存在了,它就不
会再去调用文档类的Serialize函数了,所以刚才我们在打开同一份文档时就没有进入CGraphicDoc
类的Serialize函数。当然,这种设计实际上是合情合理的。例如在Word文档中编辑一个文本时,当
编辑完成之后将它保存,然后在没有关闭该窗口的情况下再去打开同一份文档,这时打开的文档数
据与当前在窗口中显示的数据是完全一样的,那么就没有必要再去打开同样的文档,这样做可以提
高效率。同样地,刚才在保存数据时,并没有保存窗口中的数据,而是直接在CGraphicDoc类的
Serialize函数中保存数据,这时在MFC框架内部会为文件关联一个文档对象,当你在打开文件时,
它发现打开的是同样的一份文件,那么它就会使用和这个文件相关联的文档对象,它认为你的数据
己经在视类窗口中,所以就没有再调用CGraphicDoc类的Serialize函数。这也是前面章节中提到的
文档/视类框架结构的特点,在此结构中,文档类负责管理数据,提供对数据的保存和加载,视类负
责显示数据,为用户提供编辑数据和修改数据的功能。 MFC提供的文档/视类/框架结构,相当于把
将数据的
处理和显示功能划分为不同的模块来完成。这种结构相当于为程序员搭建了一个框架,程
序员只需要遵照此框架去完成内部的具体实现就可以了。 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -