基于MFC实现类的序列化详解
序列化是将程序中的对象以一种二进制格式存储到存储设备中(例如文本/数据库等),以实现“永生”或随意“流动”
首先定义一个要序列化的类people,其属性有age、weight、height。
#pragma once class people { public: int age; int weight; int height; };
定义好后将该类添加到 项目名view.h 的类中,作为其属性,并且是指针类型
将需要存取的类实现序列化
1.序列化的类必须从CObject派生,或是从CObject的派生类派生
#pragma once //导入#include<afx.h>头文件,使类能继承CObject #include<afx.h> class people :public CObject { public: int age; int weight; int height; };
2.为该类定义一个不带参数的构造函数
3.在类声明中使用DECLARE_SERIAL(类名)宏
#pragma once #include<afx.h> class people :public CObject { public: DECLARE_SERIAL(people); people(); public: int age; int weight; int height; };
4.在类的实现中添加IMPLEMENT_SERIAL(类名,父类名,版本号)宏
#include "pch.h" #include "people.h" //第一个参数是类的名字,第二个参数是父类名字,第三个参数是版本号(一般版本号从1开始) IMPLEMENT_SERIAL(people, CObject, 1); people::people() { }
5.在类的实现中,通过类向导添加Serialize虚函数(也可也手写)
MFC提供了CArchive类可以将对象数据保存到永久设备,比如磁盘文件。当应用程序重新启动后,CArchive类可以帮助我们从磁盘文件读取这些数据,然后在内存中重新构建对应的对象;这样就使得我们的对象数据永久存在,该过程称之为序列化(或者串行化)。
void people::Serialize(CArchive& ar) { if (ar.IsStoring()) { // storing code } else { // loading code } }
CArchive类重载了输入输出运算符,在存取时就是利用运算符重载
void people::Serialize(CArchive& ar) { if (ar.IsStoring()) { // storing code //存数据 ar << age << weight << height; } else { // loading code //读数据 ar >> age >> weight >> height; } }
如果说类的属性中有自定义类型的数组,比如下面这种,其中CPoint是MFC类型对象
#pragma once #include<afx.h> class people :public CObject { public: CArray<CPoint>m_point; };
那么在 Serialize设置存取时可以安这样
void people::Serialize(CArchive& ar) { if (ar.IsStoring()) { // storing code //存数据 ar << age << weight << height; } else { // loading code //读数据 ar >> age >> weight >> height; } /*直接使用数组调用该方法,因为数组已经实现了这个方法,数组存放的元素是CPoint,CPoint 本省也是支持序列化*/ m_point.Serialize(ar); }
在程序启动时加载序列化
在Doc.cpp文件中找到序列化接口函数
void Cdraw3Doc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: 在此添加存储代码 } else { // TODO: 在此添加加载代码 } }
从view类里拿到要序列化的数据people*
void Cdraw3Doc::Serialize(CArchive& ar) { //取出第一个view在链表中的位置 POSITION pos = GetFirstViewPosition(); //通过位置获得该view Cdraw3View* pView = (Cdraw3View* )GetNextView(pos); if (ar.IsStoring()) { //存数据 ar << pView->human; } else { //取数据 ar >> pView->human; } }
这样我们每次保存时数据就可以以二进制序列化保存,每次打开时又可以打开上次保存的内容
如果people*是一个数组的话,例如这样
那么我们在用序列化存取时就要先存取数组长度,再循环存取数组的内容
void Cdraw3Doc::Serialize(CArchive& ar) { //取出第一个view在链表中的位置 POSITION pos = GetFirstViewPosition(); //通过位置获得该view Cdraw3View* pView = (Cdraw3View* )GetNextView(pos); //获得数组长度 int cnt = pView->human.GetSize(); if (ar.IsStoring()) { //存数据 ar << cnt; for (int i = 0; i < cnt; i++) { //循环存储数组 ar << pView->human.GetAt(i); } } else { //取长度 ar >> cnt; for (int i = 0; i < cnt; ++i) { //依次取数据,加入到数组中 people* p; ar >> p; pView->human.Add(p); } } }
到此这篇关于基于MFC实现类的序列化详解的文章就介绍到这了,更多相关MFC类的序列化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!