MFC:初步理解序列化与反序列化(含代码实现)
序列化与反序列化是MFC将对象数据以二进制数据流的形式进行存储和读取的机制,读、写的效率很高。通过序列化与反序列化,可以将程序中对象在内存中数据保存到文件 (磁盘) 或者从文件 (磁盘) 中读取到内存以恢复对象数据,从而实现程序对数据的持续管理。其中,序列化是指从内存到文件 (硬盘) 的存储操作;而反序列化则是指从文件 (硬盘) 到内存的读取操作。
其程序实现的基本思路是利用文档类对象维护内存中数据,利用文件类对象维护硬盘文件数据,将二者联系起来的是归档类对象;利用这三个类的相互关联实现序列化 (含反序列化)目的。
一、序列化、反序列相关类及作用
1、文档类CDocument,顾名思义,这个类是MFC中专职管理数据的类。而所谓序列化反序列化的概念也是针对这个类而言的,我们在这个类内可以进行序列化(含反序列化)声明,序列化声明及实现是其它所有操作的前提条件。
通过构造继承自CDocument的自定义类,用其成员变量作为序列化或反序列化数据在内存中的载体,并通过重写它的成员虚函数Serialize实现序列化或(反序列化的具体操作,归档类对象作为参数被引入,实现文档类与归档类的关联。
2、文件操作类CFile,作用是完成硬盘文件的读、写、存操作。成员函数包括Open (打开
文件)、Read (读文件)、Write (写文件)、Close (关闭文件) 等。文件操作类对象作为参数被归档类对象构造函数引入,与归档类对象实现关联。
3、归档类CArchive,是用于数据流的封装类,完成内存数据的二进制读、写操作。归档类
对象首先被文档类虚函数Serialize作为参数引入;接下来,CArchive的构造函数通过其第一个
参数与文件类建立联系;并使用重载的">>"、"<<"进行读取与写入操作。CArchive对象和CFile对
象一样,用毕也需调用close函数关闭。归档类对象也有自己的成员函数,如IsStoring等。归档
类对象在三个类之间起中介作用。
二、代码实现
这里的代码是基于VS2022 C++空项目调用MFC静态库编制的,头文件中需要包含MFC要求
的<afxwin.h>;使用的字符集为多字符集;运行结果显示在控制台窗口。具体步骤为:
1、类的声明及相关函数等的实现
a、公开继承 CDocument 类声明一个文档类对象;
b、类内进行序列化声明并在类外实现;
c、类内public方式声明对象成员变量,这些成员变量是进行序列化 \ 反序列化的载体;
d、类内声明文档类对象构造函数并在类外实现,构造函数用于接收输入数据;
e、类内声明重写Serialize序列化虚函数并在类外实现。重写虚函数的目的是为了在
文档类与CArchive类之间建立关联,CArchive对象以参数形式进入虚函数。
2、序列化实现过程(子程序)
a、使用CFile类对象调用Open函数创建或打开文件,文件打开方式与归档类对象读写状态
要一致;
b、使用CArchive类及构造函数定义归档类对象;
c、将屏幕输入数据保存进文档类对象;
d、使用CAchive对象将文档类对象数据写入文件;
e、调用Close函数关闭归档类对象;
f、调用Close函数关闭文件类对象。
3、反序列化实现过程(子程序)
a、使用CFile类对象调用Open函数创建或打开文件 ;
b、使用CArchive类及构造函数定义归档类对象;
c、定义文档类指针对象;
d、使用CAchive对象将文件数据读取到内存并转给文档类对象
e、利用文档类对象接收数据进行屏幕显示
f、调用Close函数关闭归档类对象
g、调用Close函数关闭文件对象
4、主函数实现
三、代码实现及相关注释
下面代码是基于VS C++空项目并调用MFC静态库编制,为此头文件中应包含进<afxwin.h>。字符集使用的是多字符集,运行结果显示在控制台窗口。具体代码及注释如下:
#include<afxwin.h>
#include<iostream>
using namespace std;
//公开继承CDocument方式声明文档类并构造用于存储或读取的数据类型
class CMyDoc :public CDocument
{ DECLARE_SERIAL(CMyDoc) //序列化(含反序列化)声明
public:CString m_Name; //成员变量int m_Age;CString m_Addr;CMyDoc(CString name = "", int age = 0, CString addr = ""); //声明构造函数用于赋值virtual void Serialize(CArchive& ar); //声明重写Serialize虚函数
};
//类外实现序列化(含反序列化)
IMPLEMENT_SERIAL(CMyDoc, CDocument, 2) //参3 为版本号随意定或NULL
//类外实现构造函数
CMyDoc::CMyDoc(CString name, int age, CString addr) //此处不再需要缺省值
{this->m_Name = name;this->m_Age = age;this->m_Addr = addr;
}
//类外实现重写Serialize虚函数(CArchive对象为参数)
void CMyDoc::Serialize(CArchive &archive)
{if (archive.IsStoring()) //归档类成员函数IsStoring返回是否写入{archive << m_Name << m_Age << m_Addr; //写入}else {archive>> m_Name >> m_Age >> m_Addr; //读取}
}
//序列化实现子程序
void dataStore()
{ CFile file; //声明文件类对象file.Open("C:\\Users\\Administrator\\Desktop\\serial.txt", CFile::modeCreate | CFile::modeWrite,NULL);//CFile类成员函数Open:参1 文件名 参2 打开模式(文件不存在则创建、写模式) 参3 接收错误信息指针//文件后缀虽然写的是txt,但存储内容是二进制格式while (TRUE){CArchive myCAr(&file, CArchive::store, 4096, NULL); //CAchive类构造函数,此函数将CArchive对象与CFile对象连接//参1 CFile对象的指针 参2 归档状态存入 参3 缓冲区大小(默认4096) 参4 指向缓冲区的指针(缺省填NULL)cout << "在姓名处输入xxxxx退出" << endl;cout << "请输入姓名:" ;char name[64];cin >> name;if (name[0]=='x'&& name[1] == 'x'&& name[2] == 'x'&& name[3] == 'x'&& name[4] == 'x') break;cout << "请输入年龄:" ;int age;cin >> age;char addr[128];cout << "请输入住址:";cin >> addr;CMyDoc data(name, age, addr); //将输入数据保存仅文档类对象myCAr << &data; //将文档类对象传入CArchive对象(序列化)myCAr.Close(); //关闭CArchive对象}file.Close(); //关闭文件类对象
}
//反序列化子程序
void dataLoad()
{CFile file;file.Open("C:\\Users\\Administrator\\Desktop\\serial.txt", CFile::modeRead,NULL);//各参数含义同dataStore(),只是参2为只读模式CArchive myCAr(&file, CArchive::load, 4096);//各参数含义同dataStore(),只是参2 为读取状态CMyDoc* pData = NULL; //定义文档类指针对象用来接收读取的数据while(TRUE){try { //连续从CArchive对象读取数据传给文档类对象并进行显示myCAr >> pData; cout << pData->m_Name << " " << pData->m_Age << " " << pData->m_Addr << endl;} catch (...) { break; }} myCAr.Close(); //关闭CArchive对象file.Close(); //关闭文件类对象
}
//主函数
int main()
{dataStore();dataLoad();system("pause");return 0;
}
/*
运行结果:
在姓名处输入xxxxx退出
请输入姓名:张三
请输入年龄:25
请输入住址:天津和平
在姓名处输入xxxxx退出
请输入姓名:李四
请输入年龄:36
请输入住址:天津红桥
在姓名处输入xxxxx退出
请输入姓名:王五
请输入年龄:27
请输入住址:天津河西
在姓名处输入xxxxx退出
请输入姓名:xxxxx
张三 25 天津和平
李四 36 天津红桥
王五 27 天津河西
请按任意键继续. . .
*/
相关文章:
MFC:初步理解序列化与反序列化(含代码实现)
序列化与反序列化是MFC将对象数据以二进制数据流的形式进行存储和读取的机制,读、写的效率很高。通过序列化与反序列化,可以将程序中对象在内存中数据保存到文件 (磁盘) 或者从文件 (磁盘) 中读取到内存以恢复对象数据,从而实现程序对数据的持…...
python程序控制结构
文章目录 一、python程序控制结构介绍二、顺序结构2.1、print()函数2.2、end参数2.3、input()函数 三、选择结构3.1选择结构的用途 四、循环结构4.1循环结构的构造4.1.1、循环结构的三个要素4.1.2、循环结构的一个要求4.1.3、循环结构的一个关系 4.2、循环语句4.2.1、while语句…...

【GD32】04 - Timer定时器
GD32中的定时器 GD32E230中有七个定时器,六种类型,其中通用的L4版本有两个,其他类型的各一个。 那我们就以通用L4这个类型来敲代码,其他流程是通用的。 通用L4 虽然每种类型的定时器都有自己的结构框图,但是其实大差…...

Golang | Leetcode Golang题解之第123题买卖股票的最佳时机III
题目: 题解: func maxProfit(prices []int) int {buy1, sell1 : -prices[0], 0buy2, sell2 : -prices[0], 0for i : 1; i < len(prices); i {buy1 max(buy1, -prices[i])sell1 max(sell1, buy1prices[i])buy2 max(buy2, sell1-prices[i])sell2 m…...

Leetcode2028. 找出缺失的观测数据
Every day a Leetcode 题目来源:2028. 找出缺失的观测数据 解法1:模拟 统计当前 m 个元素的总和 curSum sum(rolls),总共 mn 个元素和为 total (m n) * mean。 排除 2 种情况: total - curSum > 6 * n:n 个…...
如何在CentOS中合理划分磁盘空间以优化系统性能
目录 前言 理想的分区方案 为什么需要单独分区 安全性 性能 管理和维护 稳定性和可靠性 升级和兼容性 结论 前言 在进行CentOS系统的安装和配置时,合理划分磁盘空间是确保系统性能、安全性和易于管理的关键步骤。本文将探讨如何根据系统的硬件配置和预期用途…...

算法(十一)贪婪算法
文章目录 算法简介算法概念算法举例 经典问题 -背包问题 算法简介 算法概念 贪婪算法(Greedy)是一种在每一步都采取当前状态下最好的或者最优的选择,从而希望导致结果也是全局最好或者最优的算法。贪婪算法是当下局部的最优判断,…...

Rust之函数式语言特性:迭代器和闭包(一):概述
开发环境 Windows 11Rust 1.78.0 VS Code 1.89.1 项目工程 这次创建了新的工程minigrep. 函数式语言特性:迭代器和闭包 Rust的设计从许多现有语言和技术中获得了灵感,其中一个重要影响是函数式编程。函数式编程通常包括通过在参数中传递函数、从其他函数返回函数、…...

配置资源管理
一 Secret Secret 是用来保存密码、token、密钥等敏感数据的 k8s 资源,这类数据虽然也可以存放在 Pod 或者镜像中,但是放在 Secret 中是为了更方便的控制如何使用数据,并减少暴露的风险。 1 有三种类型: kubernetes.io/service…...

unity2020打包webGL时卡进程问题
我使用的2020.3.0f1c1,打包发布WEB版的时候会一直卡到asm2wasm.exe这个进程里,而且CPU占用率90%以上。 即使是打包一个新建项目的空场景也是同样的问题,我尝试过一直卡在这里会如何,结果还真打包成功了。只是打包一个空场景需要20…...
云原生架构相关技术_3.无服务器技术
1.技术特点 1.1面向特定领域的后端云服务(BaaS) 随着以Kubernetes为代表的云原生技术成为云计算的容器界面,Kubernetes成为云计算的新一代操作系统。面向特定领域的后端云服务(BaaS)则是这个操作系统上的服务API&…...

Leetcode:Z 字形变换
题目链接:6. Z 字形变换 - 力扣(LeetCode) 普通版本(二维矩阵的直接读写) 解决办法:直接依据题目要求新建并填写一个二维数组,最后再将该二维数组中的有效字符按从左到右、从上到下的顺序读取并…...
Python 3 判断文件是否存在
1 使用os.path模块 import osfile_path hello.txtif os.path.exists(file_path):print(f"文件 {file_path} 存在。") else:print(f"文件 {file_path} 不存在。") 2 使用pathlib模块 from pathlib import Pathfile_path Path(word.txt)if file_path.ex…...

(深度学习记录)第TR3周:Transformer 算法详解
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 文本的输入处理中,transformer会将输入文本序列的每个词转化为一个词向量,我们通常会选择一个合适的长度作为输入…...
谷神前端组件增强:自定义列
初始化 $gp.customColumn {}initColumnPool /*** initColumnPool* 初始化列池* * param prefix 前缀* param length 长度* * return Array 列ID数组* */ function initColumnPool (prefix, length) {return Array.from({length}, (value, index) > prefix index) } self…...
31-ESP32-S3-WIFI篇-02 Event Group (事件标记组)
ESP32-S3-WIFI 事件标记组 介绍 在ESP32-S3的WiFi驱动程序中,事件标记组(Event Group)是一个非常重要的概念。它是FreeRTOS中的一种同步机制,用于在任务之间传递和同步事件。在WiFi驱动程序中,我们使用事件标记组来通…...

构建企业级AI私有知识库
一、引言 在当今竞争激烈的市场环境中,企业为了保持竞争优势,需要高效地管理和利用内部知识资源。构建一个企业级AI私有知识库,不仅可以集中存储和管理企业知识,还能通过人工智能技术实现知识的智能化处理和利用。本文将详细介绍…...

C语言王国——杨氏矩阵
目录 1. 引言 2. 了解杨氏矩阵 3. 思路分析 4. 代码 5. 总结 1. 引言 最近在做二维数组的训练的时候发现了一个很有意思的题: 一看这不是杨氏矩阵嘛,接下来就由姜糖我带大家了解一下这个著名的矩阵。 2. 了解杨氏矩阵 通过查阅百度得知: …...
陪玩小程序都需要怎么做?
开发陪玩小程序需要进行全面的需求分析、功能规划、技术选型、界面设计等一系列步骤。陪玩小程序作为一种新兴的网络服务平台,为用户提供了寻找游戏伙伴、预约陪玩服务等功能,满足了用户在游戏领域的社交互动和技能提升需求。具体分析如下: 需…...
postgressql——子事务可见性判断 性能问题(8)
子事务可见性判断 & 性能 测试SQL BEGIN; PREPARE sel(integer) ASSELECT count(*)FROM contendWHERE id BETWEEN $1 AND $1 + 100; PREPARE upd(integer) ASUPDATE contend SET val = val + 1WHERE id IN ($1, $1 + 10, $1 + 20, $1 + 30);SAVEPOINT a; \set rnd random…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...