[zz]Visual C++中对象的序列化与文件I/O研究

C++图书管理系统实战:从面向对象设计到文件I/O的完整项目指南 面向对象编程(OOP)是软件工程的核心范式,通过封装、继承和多态三大特性,将现实世界实体抽象为类,实现代码的高内聚、低耦合。其原理在于将数据与操作数据的方法绑定,构建模块化、可复用的软件组件。在工程实践中,OOP能显著提升代码的可维护性和扩展性,尤其适用于业务逻辑清晰的中小型系统开发。文件I/O(输入/输出)则是数据持久化的关键技术,涉及数据在内存与外部存储(如文本文件、二进制文件)间的序列化与反序列化过程,确保程序状态在关闭后得以保存。结合STL容器(如std::map)进行高效数据管理,开发者可以构建功 阅读详情

持久性和序列化

  持久性是对象所有的保存和加载其状态数据的能力。具有这种能力的对象能够在应用程序结束之前以某种方式将当前的对象状态数据记录下来,当程序再次运行时,通过对这些数据的读取而恢复到上一次任务结束时的状态。由于绝大多数的MFC类是直接或间接由MFC的CObject类派生出来的,因此这些MFC类都具有保存和加载对象状态的能力,是具有持久性的。在使用应用程序向导生成文档/视结构的程序框架时,就已经为应用程序提供了用于对象状态数据保存和加载的基本代码。

  为实现对象的持久性,通常多以字节流的形式将记录对象状态的数据存放到磁盘上,这种将状态数据保存到磁盘和从磁盘恢复到内存的过程称为序列化。序列化是MFC的一个重要概念,是MFC文档/视图结构应用程序能进行文档打开、保存等操作的基础。当在MFC框架程序中装载或保存一个文件时,除了打开文件以供程序读写外,还传递给应用程序一个相关的CArchive对象,并以此实现对持久性数据的序列化。

  大多数MFC应用程序在实现对象的持久性时并非直接用MFC的CFile类对磁盘文件进行读写(有关CFile类的详细介绍将在下一节进行),而是通过使用CArchive对象并由其对CFile成员函数进行调用来执行文件I/O操作。CArchive类支持复合对象的连续二进制形式的输入输出。在构造一个CArchive对象或将其连接到一个表示打开的文件的CFile对象后,可以指定一个档案是被装载还是被保存。MFC允许使用操作符“<<”和“>>”来对多种原始数据类型进行序列化。这些原始数据类型包括BYTE,WORD,LONG,DWORD,float,double,int,unsigned int,short和char等。

  对于其他由MFC类来表示的非原始数据类型如CString对象等的序列化则可以通过对“<<”和“>>”运算符的重载来解决,可以用此方式进行序列化的MFC类和结构有CString,CTime,CTimeSpan,COleVariant,COleCurreny,COleDateTime,COleDateTimeSpan,CSize,CPoint,CRect,SIZE,POINT和RECT等。除了操作符“<<”和“>>”之外还可以调用CArchive类成员函数Read()和Write()来完成序列化。下面这段代码展示了通过操作符对int型变量VarA、VarB的序列化过程:

// 将VarA、VarB存储到档案中
CArchive ar (&file, CArchive::store);
ar << VarA << VarB;
……
// 从档案装载VarA、VarB
CArchive ar (&file, CArchive::load)
ar >> VarA >> VarB;


  CArchive类仅包含有一个数据成员m__pDocument。在执行菜单上的打开或保存命令时,程序框架将会把该数据成员设置为要被序列化的文档。另外需要特别注意的是:在使用CArchive类时,要保证对CArchive对象的操作与文件访问权限的统一。

  在本文下面将要给出的示例程序中,将对绘制连线所需要的关键点坐标和坐标个数等持久性对象进行序列化。其中文档类的成员变量m_nCount和m_ptPosition[100]分别记录了当前点的个数和坐标,初始值为0。当鼠标点击客户区时将对点的个数进行累加,并保存当前点的坐标位置。随后通过Invalidate()函数发出WM_PAINT消息通知窗口对客户区进行重绘,在重绘代码中对这些点击过的点进行绘图连线:

void CSample04View::OnLButtonDown(UINT nFlags, CPoint point)
{
 // 获取指向文档类的指针
 CSample04Doc* pDoc = GetDocument();
 // 保存当前鼠标点击位置
 pDoc->m_ptPosition[pDoc->m_nCount] = point;
 if (pDoc->m_nCount < 100)
  pDoc->m_nCount++;
 // 刷新屏幕
 Invalidate();
 CView::OnLButtonDown(nFlags, point);
}
……
void CSample04View::OnDraw(CDC* pDC)
{
 CSample04Doc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // 对点击的点进行连线绘图
 pDC->MoveTo(pDoc->m_ptPosition[0]);
 for (int i = 1; i < pDoc->m_nCount; i++)
  pDC->LineTo(pDoc->m_ptPosition[i]);
}



  从上述程序代码不难看出,为了能保存绘制结果需要对文档类的成员变量m_nCount和m_ptPosition[100]进行序列化处理。而文档类成员函数Serialize()则通过Archive类为这些持久性对象的序列化提供了功能上的支持。下面的代码完成了对持久性对象的保存和加载:

if (ar.IsStoring())
{
 // 存储持久性对象到档案
 ar << m_nCount;
 for (int i = 0; i < m_nCount; i++)
  ar << m_ptPosition[i];
}
else
{
 // 从档案装载持久性对象
 ar >> m_nCount;
 for (int i = 0; i < m_nCount; i++)
  ar >> m_ptPosition[i];
}


  文件I/O

  虽然使用CArchive类内建的序列化功能是保存和加载持久性数据的便捷方式,但有时在程序中需要对文件处理过程拥有更多的控制权,对于这种文件输入输出(I/O)服务的需求,Windows提供了一系列相关的API函数,并由MFC将其封装为CFile类,提供了对文件进行打开,关闭,读,写,删除,重命名以及获取文件信息等文件操作的基本功能,足以处理任意类型的文件操作。CFile类是MFC文件类的基类,支持无缓冲的二进制输入输出,也可以通过与CArchive类的配合使用而支持对MFC对象的带缓冲的序列化。

  CFile类包含有一个公有型数据成员m_hFile,该数据成员包含了同CFile类对象相关联的文件句柄。如果没有指定句柄,则该值为CFile::hFileNull。由于该数据成员所包含的意义取决于派生的类,因此一般并不建议使用m_hFile。

  通过CFile类来打开文件可以采取两种方式:一种方式是先构造一个CFile类对象然后再调用成员函数Open()打开文件,另一种方式则直接使用CFile类的构造函数去打开一个文件。下面的语句分别演示了用这两种方法打开磁盘文件“C:/TestFile.txt”的过程:

// 先构造一个实例,然后再打开文件
CFile file;
file.Open(“C://TestFile.txt”, CFile::modeReadWrite);
……
// 直接通过构造函数打开文件
CFile file(“C://TestFile.txt”, CFile::modeReadWrite);

  其中参数CFile::modeReadWrite是打开文件的模式标志,CFile类中与之类似的标志还有十几个,现集中列表如下:

文件模式标志
说明
CFile::modeCreate 创建方式打开文件,如文件已存在则将其长度设置为0
CFile::modeNoInherit 不允许继承
CFile::modeNoTruncate创建文件时如文件已存在不对其进行截断
CFile::modeRead只读方式打开文件
CFile::modeReadWrite读写方式打开文件
CFile::modeWrite写入方式打开文件
CFile::shareCompat在使用过程中允许其他进程同时打开文件
CFile::shareDenyNone在使用过程中允许其他进程对文件进行读写
CFile::shareDenyRead在使用过程中不允许其他进程对文件进行读取
CFile::shareDenyWrite在使用过程中不允许其他进程对文件进行写入
CFile::shareExclusive 取消对其他进程的所有访问
CFile::typeBinary设置文件为二进制模式
CFile::typeText设置文件为文本模式

  这些标志可以通过“或”运算符而同时使用多个,并以此来满足多种需求。例如,需要以读写方式打开文件,如果文件不存在就创建一个新的,如果文件已经存在则不将其文件长度截断为0。为满足此条件,可用CFile::modeCreate、CFile::modeReadWrite和CFile::modeNoTruncate等几种文件模式标志来打开文件:

CFile file ("C://TestFile.txt", CFile::modeCreate | CFile::modeReadWrite | CFile::modeNoTruncate);

  在打开的文件不再使用时需要将其关闭,即可以用成员函数Close()关闭也可以通过CFile类的析构函数来完成。当采取后一种方式时,如果文件还没有被关闭,析构函数将负责隐式调用Close()函数去关闭文件,这也表明创建在堆上的CFile类对象在超出范围后将自动被关闭。由于调用了对象的析构函数,因此在文件被关闭的同时CFile对象也被销毁,而采取Close()方式关闭文件后,CFile对象仍然存在。所以,在显式调用Close()函数关闭一个文件后可以继续用同一个CFile对象去打开其他的文件。

  文件读写是最常用的文件操作方式,主要由CFile类成员函数Read()、Write()来实现。其函数原型分别为:

UINT Read( void* lpBuf, UINT nCount );
void Write( const void* lpBuf, UINT nCount );

  参数lpBuf为指向存放数据的缓存的指针,nCount为要读入或写入的字节数,Read()返回的为实际读取的字节数,该数值小于或等于nCount,如果小于nCount则说明已经读到文件末尾,可以结束文件读取,如继续读取,将返回0。因此通常可以将实际读取字节数是否小于指定读取的字节数或是否为0作为判断文件读取是否到达结尾的依据。下面这段代码演示了对文件进行一次性写入和循环多次读取的处理过程:

// 创建、写入方式打开文件
CFile file;
file.Open("C://TestFile.txt", CFile::modeWrite | CFile::modeCreate);
// 写入文件
memset(WriteBuf, 'a', sizeof(WriteBuf));
file.Write(WriteBuf, sizeof(WriteBuf));
// 关闭文件
file.Close();
// 只读方式打开文件
file.Open("C://TestFile.txt", CFile::modeRead);
while (true)
{
// 读取文件数据
int ret = file.Read(ReadBuf, 100);
……
// 如果到达文件结尾则中止循环
if (ret < 100)
break;
}
// 关闭文件
file.Close();

  Write()和Read()函数执行完后将自动移动文件指针,因此不必再显示调用Seek()函数去定位文件指针。包含有文件定位函数的完整代码如下所示:

// 创建、写入方式打开文件
CFile file;
file.Open("C://TestFile.txt", CFile::modeWrite | CFile::modeCreate);
// 写入文件
memset(WriteBuf, 'a', sizeof(WriteBuf));
file.SeekToBegin();
file.Write(WriteBuf, sizeof(WriteBuf));
// 关闭文件
file.Close();
// 只读方式打开文件
file.Open("C://TestFile.txt", CFile::modeRead);
while (true)
{
// 文件指针
static int position = 0;
// 移动文件指针
file.Seek(position, CFile::begin);
// 读取文件数据
int ret = file.Read(ReadBuf, 100);
position += ret;
……
// 如果到达文件结尾则中止循环
if (ret < 100)
break;
}
// 关闭文件
file.Close();

  小结

  持久性和文件I/O是程序保持和记录数据的一种重要方法,这两种不同的处理方法虽然功能上有些接近但实现过程却大不相同。而且这两种处理方法各有优势,读者在编程过程中应根据实际情况而灵活选用。

69、SAP数据库归档重做日志备份策略与工具详解 本文详细解析了SAP数据库归档重做日志备份的重要性及策略,介绍了SAP提供的备份工具brarchive及其配置和使用方法,探讨了BRBACKUP与BRARCHIVE的联合运行、一致在线备份、备用数据库备份场景以及备份策略的综合应用与优化。此外,还分析了备份过程中常见问题的解决方法、备份监控与评估流程、与第三方备份解决方案的集成方式,以及未来备份技术的发展趋势和应对策略。通过合理运用这些策略和工具,可以有效保障SAP数据库的安全性和可恢复性。 阅读详情

相关推荐

避开这5个坑!Tushare数据获取与清洗的常见问题解决方案

本文详细解析了使用Tushare进行金融数据分析时常见的5大问题,包括Token失效、数据缺失、频率限制等,并提供了Python实战解决方案。通过智能填充策略、队列化管理和分层存储设计,帮助开发者高效获取和清洗金融数据,提升量化分析效率。特别适合金融数据分析师和Python开发者参考。

f9g0h的博客 419

Qt之添加Windows资源文件(.rc文件)

简述 在Windows下使用Qt时,通常会用到Windows的资源文件 - 为exe设置信息,其中包括:文件说明、产品名称、产品版本、版权等信息。。。 由于是Windows平台相关的东西,Qt助手中对于rc文件几乎没有任何介绍(在Setting the Application Icon一文中简单提到)。 简述 资源信息 ...

weixin_34138521的博客 942

qPCRtools | 神仙R包分分钟搞定你的qPCR实验结果!~

1写在前面 不知道大家都是怎么完成qPCR的计算的,在不会R的时候,我是用一个祖传的Excel表进行计算的。🤣 但是,一直有个缺点,如果需要计算的量比较大时,就不方便了,去搜了一下文献,发现了一个最近发表的R包,不仅可以计算反转录的RNA体积,还可以帮助选择定量方法,简直是神仙R包,本期就介绍一下它的使用吧。🥰 感谢原作者的开发,嘿嘿,文末有引用方法。👀 2用到的包 rm(list = ls())library(tidyverse)library(ggsci)library(qPCRtools)librar

m0_72224305的博客 3985

C++编程中使用框架protobuf

C++语言使用protobuf框架

hsy12342611的专栏 5942

iverilog+GTKwave使用总结

iverilog是一个开源的硬件描述语言(HDL)仿真工具,用于对硬件描述语言(如Verilog)编写的数字电路进行仿真。它可以将Verilog代码编译为仿真模型,并通过仿真运行来验证设计的正确性。iverilog支持IEEE 1364-2005 Verilog语言标准,并提供了丰富的功能,包括对多种Verilog语言特性的支持、模块化设计、测试平台等。它还可以与其他工具(如GTKWave波形查看器)配合使用,以便进行仿真后的波形查看和分析。

争取早日成为硅农 2万+

CXL Virtual Hierarchy (VH) Enumeration理解

在 CXL 3.0 协议中,CXL Virtual Hierarchy (VH) Enumeration 是一种针对 CXL 虚拟层级(Virtual Hierarchy) 设计的设备枚举机制,它允许软件将物理连接的 CXL 设备抽象为多个逻辑层级(虚拟层级),从而实现更灵活的资源管理和拓扑扩展。与传统的 PCIe 枚举相比,CXL VH 枚举在协议特性、拓扑抽象和资源分配机制上有显著差异。本质:VH 是一个逻辑上的设备层级结构,可能与物理连接拓扑不同。

Summer的博客 1001

Visual C++中对象的序列化与文件I/O研究

Visual C++中对象的序列化与文件I/O研究 持久性和序列化   持久性是对象所有的保存和加载其状态数据的能力。具有这种能力的对象能够在应用程序结束之前以某种方式将当前的对象状态数据记录下来,当程序再次运行时,通过对这些数据的读取而恢复到上一次任务结束时的状态。由于绝大多数的MFC类是直接或间接由MFC的CObject类派生出来的,因此这些MFC类都具有保存和加载对象状态的能力,是具

Win32Boy的专栏 1801

数据工程师——ETL

文章摘要 ETL(数据抽取、转换、加载)是数据处理的核心流程,负责将分散数据源整合为高质量数据。ETL与ELT的主要区别在于转换步骤顺序,分别适用于不同规模数据场景。数据仓库通过ETL从多个数据源集成数据,支持分析决策。维度建模中的事实表记录业务指标,维度表提供上下文信息。缓慢变化维度(SCD)处理随时间变化的维度数据,常见类型包括直接覆盖型、新增版本型等。数据清洗解决数据缺失、重复、错误等问题,确保数据质量。数据血缘记录数据流转路径,便于问题排查和影响分析。常用ETL工具如Kettle通过转换和作业实现数

weixin_45729710的博客 1559

VC程序设计中可序列化类的实现

内容提要:本文以简单的例子介绍在Visual C++编程中数据读写的基本方法和可序列化类的实现,并简单介绍了Visual C++中序列化的使用。   数据读写是应用程序中必不可少的一部分,Visual C++中数据的读写当然也十分重要,因此VisualC++在MFC中对数据的读写创造了十分好的支持,这使得我们可以十分方便的实现我们对数据读写操作的需要。  MFC 为数据读写设计了...

weixin_30776863的博客 250

目标检测YOLO实战应用案例100讲-基于数据融合的SAR图像中海上目标检测与跟踪(中)

本文使用的数据集为欧空局(European Space Agency, ESA)提供的Sentinal-1 数据集,Sentinel-1是欧洲“哥白尼计划”的SAR卫星机群,主要是用于陆地和海 洋服务的极地轨道全天候昼夜雷达成像任务[ 34]。Sentinel-1A于2014年4月3日发 射升空,Sentinel-1B于2016年4月25日发射升空,每颗卫星都携带C波段SAR, 共同提供地球表面的全天候、昼夜图像。

qq_36130719的博客 356

lammps案例:聚乙烯和石墨烯界面pull out模拟

大家好,我是小马老师。 本文介绍lammps模拟计算界面结合力的一个案例。 本案例参考论文《The interfacial mechanical properties of functionalized graphene- polymer nanocomposites》,对论文作者表示感谢。 模型共分2层,上层为聚乙烯模型,下次为单层石墨烯,模拟过程共分3部分:建模、弛豫、拉伸。 (1)建模 使用MS建立聚乙烯和石墨烯模型,具体方法可参考之前的推文,使用build layer方法建立聚乙烯和石墨烯组合模型,

lammps_jiayou的博客 3493

C++数据序列化之MessagePack

msgpack官方地址:http://msgpack.org/ msgpack GITHUB地址:https://github.com/msgpack 对于msgPack,官方是这样解释的: MessagePack  是一个高效的二进制序列化格式。它让你像JSON一样可以在各种语言之间交换数据。但是它比JSON更快、更小。小的整数会被编码成一个字节,短的字符串仅仅只需要比它的长度多一

sky_0035的专栏 3639

FreeRTOS全攻略:从入门到精通

本文聚焦 FreeRTOS,从基础概念出发,阐述其开源、轻量级等优势。着重介绍 FreeRTOS 入门知识,涵盖内存管理、任务操作、同步互斥机制等核心内容。其中,空闲任务与钩子函数保障系统基础运行与功能扩展;队列、信号量、互斥锁和事件组等机制,分别从数据传递、资源访问控制、优先级问题解决及多任务同步等方面,为开发者提供高效的任务间协作与资源管理方案,助力开发者掌握 FreeRTOS 核心技术,为嵌入式项目开发筑牢基础。

邓邓子的博客 6357

Visual C++中对象的序列化与文件I/O研究【转帖】

串行化 文件I/O

Polaris 454

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Visual C++中对象的序列化与文件I/O

持久性和序列化   持久性是对象所有的保存和加载其状态数据的能力具有这种能力的对象能够在应用程序结束之前以某种方式将当前的对象状态数据记录下来当程序再次运行时通过对这些数据的读取而恢复到上一次任务结束时的状态由于绝大多数的MFC类是直接或间接由MFC的CObject类派生出来的因此这些MFC类都具有保存和加载对象状态的能力是具有持久性的在使用应用程序向导生成文档/视结构的程序框架时就已经为应用程

zjc156m的专栏 1137

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C++旅馆管理系统课程设计:面向对象编程与文件I/O实战

面向对象编程(OOP)是构建复杂软件系统的核心范式,它通过封装、继承和多态等特性,将现实世界的实体抽象为类与对象,从而提升代码的可读性、可维护性和复用性。其原理在于将数据与操作数据的方法绑定,形成高内聚、低耦合的模块。在工程实践中,OOP的价值在于能够清晰地对业务领域进行建模,例如在管理系统中,可以自然地映射出“房间”、“客人”等实体类。数据持久化是另一个基础且关键的技术概念,它解决了程序运行状态在关闭后得以保存的问题,常见实现方式包括文件I/O和数据库操作。通过文件读写,可以将内存中的对象序列化存储到磁盘

weixin_34268310的博客 401

C++课程设计实战:面向对象与文件I/O实现杂志订阅管理系统

面向对象程序设计(OOP)是软件工程的核心思想,通过封装、继承和多态三大特性,将现实世界实体抽象为类与对象,构建模块化、可复用的代码结构。其原理在于将数据与操作数据的方法绑定,实现高内聚低耦合的设计。在工程实践中,结合数据结构(如STL容器)与文件I/O操作,能够将内存中的对象持久化存储,这是构建桌面应用与管理系统的基础能力。本文以经典的“杂志订阅管理系统”为例,深入解析如何运用C++的类设计、STL容器(map/vector)管理数据,并通过自定义文本格式实现健壮的文件存储,为课程设计及中小型CRUD系统

weixin_33735077的博客 520

C++学生成绩管理系统:从STL容器到文件I/O的完整项目实践

在C++编程学习中,数据结构与算法是核心基础,而STL(标准模板库)容器则是连接理论与工程实践的关键桥梁。vector、list等容器封装了底层内存管理,提供了高效、安全的动态数组和链表实现,极大提升了开发效率。理解其原理,掌握其应用,是构建健壮软件系统的基石。文件I/O操作则是实现数据持久化的核心技术,确保程序数据在关闭后不丢失。将STL容器与文件I/O结合,能够构建出具备完整CRUD(增删改查)功能的管理系统,这正是许多课程设计的经典选题。本文以学生成绩管理系统为例,深入剖析如何运用vector管理学生

weixin_33910385的博客 430
上一篇: [MFC]对象序列化
下一篇: VS2008调试后幽灵窗口解决办法
barech
博客等级 码龄21年 137粉丝 99原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值