当前位置: 首页 > news >正文

如何实现序列化和反序列化?如何处理对象的生命周期管理?

序列化和反序列化

实现思路

  • 序列化:将对象的状态信息转换为可以存储或传输的格式,通常是字节流。
    1. 确定要序列化的对象的数据成员。
    2. 将这些数据成员按照一定的规则(如二进制、文本、JSON、XML 等)编码为字节序列。
    3. 将生成的字节序列存储到文件或发送到网络。
  • 反序列化:将字节流恢复为对象的状态信息。
    1. 从文件或网络接收字节序列。
    2. 按照序列化时使用的规则解码字节序列。
    3. 根据解码后的数据成员创建或更新对象。
#include <iostream>
#include <fstream>
#include <string>class SerializableObject {
private:int data1;double data2;std::string data3;public:SerializableObject(int d1 = 0, double d2 = 0.0, const std::string& d3 = "") : data1(d1), data2(d2), data3(d3) {}// 序列化函数void serialize(const std::string& filename) const {std::ofstream file(filename, std::ios::binary);if (file.is_open()) {// 写入数据成员file.write(reinterpret_cast<const char*>(&data1), sizeof(data1));file.write(reinterpret_cast<const char*>(&data2), sizeof(data2));// 先写入字符串长度size_t len = data3.length();file.write(reinterpret_cast<const char*>(&len), sizeof(len));// 再写入字符串内容file.write(data3.c_str(), len);file.close();} else {std::cerr << "Failed to open file for serialization." << std::endl;}}// 反序列化函数void deserialize(const std::string& filename) {std::ifstream file(filename, std::ios::binary);if (file.is_open()) {// 读取数据成员file.read(reinterpret_cast<char*>(&data1), sizeof(data1));file.read(reinterpret_cast<char*>(&data2), sizeof(data2));// 先读取字符串长度size_t len;file.read(reinterpret_cast<char*>(&len), sizeof(len));// 再读取字符串内容data3.resize(len);file.read(&data3[0], len);file.close();} else {std::cerr << "Failed to open file for deserialization." << std::endl;}}void display() const {std::cout << "data1: " << data1 << ", data2: " << data2 << ", data3: " << data3 << std::endl;}
};int main() {SerializableObject obj(42, 3.14, "Hello, World!");std::string filename = "object.bin";// 序列化obj.serialize(filename);std::cout << "Serialized object: " << std::endl;obj.display();SerializableObject newObj;// 反序列化newObj.deserialize(filename);std::cout << "Deserialized object: " << std::endl;newObj.display();return 0;
}

代码解释

  • SerializableObject 类包含三个数据成员:data1(整数)、data2(双精度浮点数)和 data3(字符串)。
  • serialize 函数:
    • 使用 std::ofstream 以二进制模式打开文件。
    • 对于 data1 和 data2,使用 file.write 将它们的二进制表示写入文件。
    • 对于 data3,先写入字符串的长度,再写入字符串的内容。
  • deserialize 函数:
    • 使用 std::ifstream 以二进制模式打开文件。
    • 对于 data1 和 data2,使用 file.read 读取它们的二进制表示。
    • 对于 data3,先读取字符串的长度,再读取字符串的内容。
  • display 函数:打印对象的数据成员。

 如何处理对象的生命周期管理?

实现思路

  • 构造函数:用于对象的初始化,可进行资源分配和成员初始化。
  • 析构函数:用于对象销毁时释放资源,如释放动态分配的内存、关闭文件等。
  • 拷贝构造函数和拷贝赋值运算符:控制对象的拷贝行为,避免浅拷贝导致的资源问题。
  • 移动构造函数和移动赋值运算符:实现对象资源的高效移动,避免不必要的拷贝。
#include <iostream>
#include <string>
#include <utility>class ResourceManagingObject {
private:int* data;size_t size;public:// 构造函数ResourceManagingObject(size_t s = 0) : size(s) {if (s > 0) {data = new int[s];for (size_t i = 0; i < s; ++i) {data[i] = i;}} else {data = nullptr;}}// 析构函数~ResourceManagingObject() {delete[] data;}// 拷贝构造函数ResourceManagingObject(const ResourceManagingObject& other) : size(other.size) {if (other.data) {data = new int[size];for (size_t i = 0; i < size; ++i) {data[i] = other.data[i];}} else {data = nullptr;}}// 拷贝赋值运算符ResourceManagingObject& operator=(const ResourceManagingObject& other) {if (this == &other) return *this;delete[] data;size = other.size;if (other.data) {data = new int[size];for (size_t i = 0; i < size; ++i) {data[i] = other.data[i];}} else {data = nullptr;}return *this;}// 移动构造函数ResourceManagingObject(ResourceManagingObject&& other) noexcept : data(other.data), size(other.size) {other.data = nullptr;other.size = 0;}// 移动赋值运算符ResourceManagingObject& operator=(ResourceManagingObject&& other) noexcept {if (this == &other) return *this;delete[] data;data = other.data;size = other.size;other.data = nullptr;other.size = 0;return *this;}void display() const {if (data) {for (size_t i = 0; i < size; ++i) {std::cout << data[i] << " ";}std::cout << std::endl;} else {std::cout << "No data." << std::endl;}}
};int main() {ResourceManagingObject obj1(5);std::cout << "Original object: ";obj1.display();// 拷贝构造ResourceManagingObject obj2 = obj1;std::cout << "Copied object: ";obj2.display();// 移动构造ResourceManagingObject obj3 = std::move(obj1);std::cout << "Moved object: ";obj3.display();std::cout << "Original object after move: ";obj1.display();return 0;
}

代码解释

  • ResourceManagingObject 类管理一个动态分配的整数数组。
  • 构造函数:根据大小分配内存并初始化数组元素。
  • 析构函数:释放动态分配的内存。
  • 拷贝构造函数和拷贝赋值运算符:深拷贝资源,避免浅拷贝导致的资源共享和潜在的内存问题。
  • 移动构造函数和移动赋值运算符:将资源从源对象移动到目标对象,源对象放弃资源所有权。

 

 

相关文章:

如何实现序列化和反序列化?如何处理对象的生命周期管理?

序列化和反序列化 实现思路&#xff1a; 序列化&#xff1a;将对象的状态信息转换为可以存储或传输的格式&#xff0c;通常是字节流。 确定要序列化的对象的数据成员。将这些数据成员按照一定的规则&#xff08;如二进制、文本、JSON、XML 等&#xff09;编码为字节序列。将生…...

WPF+MVVM案例实战与特效(三十八)- 封装一个自定义的数字滚动显示控件

文章目录 1、运行效果2、案例实现1、功能设计2、页面布局3、控件使用4、运行效果3、拓展:多数字自定义控件1、控件应用4、总结1、运行效果 在Windows Presentation Foundation (WPF)应用程序中,自定义控件允许开发者创建具有特定功能和外观的独特UI元素。本博客将介绍一个名…...

docker安装Redis、docker使用Redis、docker离线安装redis、Redis离线安装

服务器到期了&#xff0c;换了一个新的环境要重搭&#xff0c;就记录一下好了&#xff1a; -----docker在线安装Redis 拉取 Redis 镜像 docker pull redis:6.2 运行 Redis 容器 docker run --name redis -d redis docker run --name redis -d redis:6.2 映射端口 docker run -…...

单目动态新视角合成

目录 单目动态新视角合成 Generative Camera Dolly:Extreme Monocular Dynamic Novel View Synthesis 单目动态新视角合成 Generative Camera Dolly: Extreme Monocular Dynamic Novel View Synthesis Generative Camera Dolly: Extreme Monocular Dynamic Novel View Synth…...

STM32--IO引脚复用

IO引脚复用...

Python字符串及正则表达式(十):字符串常用操作、字符串编码转换

前言&#xff1a;在编程的世界里&#xff0c;字符串无处不在。它们是构建用户界面、存储数据、进行通信的基础元素。无论是财务系统的总账报表、电子游戏的比赛结果&#xff0c;还是火车站的列车时刻表&#xff0c;这些信息最终都需要以文本的形式呈现给用户。这些文本的背后&a…...

前端的Python入门指南(完):错误和异常处理策略及最佳实践

《前端的 Python 入门指南》系列文章&#xff1a; &#xff08;一&#xff09;&#xff1a;常用语法和关键字对比&#xff08;二&#xff09;&#xff1a;函数的定义、参数、作用域对比&#xff08;三&#xff09;&#xff1a;数据类型对比 - 彻底的一切皆对象实现和包装对象异…...

LeetCode 2475 数组中不等三元组的数目

问题描述: 给定一个下标从 0 开始的正整数数组 nums&#xff0c;我们的目标是找出并统计满足下述条件的三元组 (i, j, k) 的数目&#xff1a; 0 < i < j < k < nums.length&#xff0c;这确保了三元组索引的顺序性。nums[i]、nums[j] 和 nums[k] 两…...

【和春笋一起学C++】字符串比较

目录 C语言字符串比较 C语言字符比较 C字符串比较 C语言字符串比较 在C语言中用于比较字符串的函数为strcmp函数&#xff0c;该函数定义在头文件<string.h>中&#xff0c;是一个标准库函数。strcmp函数的工作原理是逐字符比较两个字符串&#xff0c;直到找到不同的字符…...

HTTP 协议报文结构 | 返回状态码详解

注&#xff1a;本文为 “HTTP 历史 | 协议报文结构 | 返回状态码” 相关文章合辑。 未整理去重。 HTTP 历史 wangjunliang 最后更新: 2024/3/16 上午10:29 超文本传输协议(英语:HyperTextTransferProtocol,缩写:HTTP)是 万维网(World Wide Web)的基础协议&#xff61;自 蒂姆…...

.net winform 实现CSS3.0 泼墨画效果

效果图 代码 private unsafe void BlendImages1(Bitmap img1, Bitmap img2) {// 确定两个图像的重叠区域Rectangle rect new Rectangle(0, 0,Math.Min(img1.Width, img2.Width),Math.Min(img1.Height, img2.Height));// 创建输出图像&#xff0c;尺寸为重叠区域大小Bitmap b…...

LearnOpenGL学习(高级OpenGL - - 实例化,抗锯齿)

实例化 对于在同一场景中使用相同顶点数据的对象&#xff08;如草地中的草&#xff09;&#xff0c;可以使用实例化&#xff08;Instancing&#xff09;技术&#xff0c;用一个绘制函数让OpenGL绘制多个物体&#xff0c;而非循环&#xff08;Drawcall: N->1&#xff09;。 …...

大数据与AI:从分析到预测的跃迁

引言&#xff1a;数据时代的新纪元 从每天的社交分享到企业的运营决策&#xff0c;数据早已成为现代社会不可或缺的资源。我们正置身于一个数据爆炸的时代&#xff0c;数以亿计的信息流实时生成&#xff0c;为人类带来了前所未有的洞察能力。然而&#xff0c;数据的价值并不仅限…...

【CC2530开发基础篇】继电器模块使用

一、前言 1.1 开发背景 本实验通过使用CC2530单片机控制继电器的吸合与断开&#xff0c;深入了解单片机GPIO的配置与应用。继电器作为一种常见的电气控制元件&#xff0c;广泛用于自动化系统中&#xff0c;用于控制大功率负载的开关操作。在本实验中&#xff0c;将通过GPIO口…...

C05S07-Tomcat服务架设

一、Tomcat 1. Tomcat概述 Tomcat也是一个Web应用程序&#xff0c;具有三大核心功能。 Java Servlet&#xff1a;Tomcat是一个Servlet容器&#xff0c;负责管理和执行Java Servlet、服务端的Java程序&#xff0c;处理客户端的HTTP请求和响应。Java Server&#xff1a;服务端…...

Java stream groupingBy sorted 实现多条件排序与分组的最佳实践

1. 数据初始化 这一部分代码用于创建 Product 对象并将它们添加到 result 列表中。 // 初始化数据 List<Product> result new ArrayList<>(); List<Product> resp new ArrayList<>();// 添加产品数据 result.add(new Product("手机A", 1…...

JAVA:代理模式(Proxy Pattern)的技术指南

1、简述 代理模式(Proxy Pattern)是一种结构型设计模式,用于为其他对象提供一种代理,以控制对这个对象的访问。通过代理模式,我们可以在不修改目标对象代码的情况下扩展功能,满足特定的需求。 设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git 2、什…...

爬取Q房二手房房源信息

文章目录 1. 实战概述2. 网站页面分析3. 编写代码爬取Q房二手房房源信息3.1 创建项目与程序3.2 运行程序&#xff0c;查看结果 4. 实战小结 1. 实战概述 本次实战项目旨在通过编写Python爬虫程序&#xff0c;抓取深圳Q房网上的二手房房源信息。我们将分析网页结构&#xff0c;…...

Ansible自动化运维(五) 运维实战

Ansible自动化运维这部分我将会分为五个部分来为大家讲解 &#xff08;一&#xff09;介绍、无密钥登录、安装部署、设置主机清单 &#xff08;二&#xff09;Ansible 中的 ad-hoc 模式 模块详解&#xff08;15&#xff09;个 &#xff08;三&#xff09;Playbook 模式详解 …...

K-means算法的python实现

K-means算法步骤 初始化质心&#xff1a;输入初始的质心位置。分配样本&#xff1a;将每个数据点分配到离它最近的质心对应的簇中。更新质心&#xff1a;对每个簇中的所有数据点&#xff0c;计算它们的均值&#xff0c;并将均值更新为新的质心。重复步骤2和3&#xff0c;直到质…...

Vite多入口页面配置实战:从单页应用到多页项目的平滑升级指南

Vite多入口页面配置实战&#xff1a;从单页应用到多页项目的平滑升级指南 当你已经用Vite构建了一个优雅的单页应用&#xff0c;突然业务需求要求你扩展为多页项目时&#xff0c;是否感到手足无措&#xff1f;别担心&#xff0c;这种架构演进在项目成长过程中再常见不过了。作为…...

小白必看:霜儿-汉服-造相Z-Turbo从部署到出图全流程解析

小白必看&#xff1a;霜儿-汉服-造相Z-Turbo从部署到出图全流程解析 1. 镜像简介与核心优势 霜儿-汉服-造相Z-Turbo是一款专为汉服写真生成优化的AI模型镜像&#xff0c;基于Xinference框架部署&#xff0c;通过Gradio提供简洁易用的Web界面。与通用文生图模型相比&#xff0…...

用Python写AI版石头剪刀布:教你用机器学习预测对手出拳(TensorFlow实战)

用Python构建AI驱动的石头剪刀布游戏&#xff1a;从数据收集到模型部署全流程 石头剪刀布这个看似简单的游戏&#xff0c;实际上蕴含着丰富的决策模式和人类行为规律。作为一名长期研究游戏AI的开发者&#xff0c;我发现用机器学习预测玩家出拳模式远比随机选择有趣得多。本文将…...

从生活沟通到AI对话:写好提示词,用好AI的魔法钥匙

一个顿悟&#xff1a;从复杂技术到简单提示最近与一位从事软件开发的朋友交流&#xff0c;他提出了一个颇具启发性的构想&#xff1a;将软件的售后客服工作交给AI来处理。起初&#xff0c;他的思路充满了技术复杂性——计划向AI提供核心代码库、训练一个专属的客服模型、进行深…...

利用快马平台与openclaw切换模型功能,快速构建待办事项应用原型

最近在尝试快速构建一个待办事项应用的原型时&#xff0c;发现InsCode(快马)平台的AI代码生成功能特别适合这种场景。通过平台内置的openclaw切换模型功能&#xff0c;可以快速比较不同AI模型生成的代码风格差异&#xff0c;大大缩短了原型开发周期。下面分享下我的实践过程&am…...

OpenClaw初学者套装:Qwen3.5-9B镜像+5个基础技能

OpenClaw初学者套装&#xff1a;Qwen3.5-9B镜像5个基础技能 1. 为什么选择这个组合&#xff1f; 上周六下午&#xff0c;我盯着电脑里散落各处的会议纪要、参考文章和代码片段&#xff0c;突然意识到自己每天要重复几十次"CtrlF→切换窗口→复制粘贴"的操作。作为一…...

ESP32 ILI9341高性能驱动:64字节DMA突发传输优化

1. 项目概述ILI9341_ESP32 是一款专为 ESP32 平台深度优化的 ILI9341 TFT LCD 显示驱动库。其核心设计目标并非简单实现显示功能&#xff0c;而是在硬件能力边界内榨取极致帧率与响应性能。该库直面 ESP32 的 SPI 总线特性——支持 64 字节一次性突发传输&#xff08;burst tra…...

LCC-S无线电能传输的Pi移相控制与SS结构效果显著

LCC-S无线电能传输pi移相控制输出电压&#xff0c;效果很棒 SS结构&#xff0c;与其他低阶高阶拓扑也可以做 SS拓扑最近在捣鼓无线电能传输系统时&#xff0c;意外发现LCC-S拓扑搭配π型移相控制&#xff0c;输出效果堪比美颜相机里的磨皮功能。这货不仅能把输出电压纹波压得比…...

2026届必备的五大AI辅助论文助手实际效果

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 基于大语言模型与自然语言处理技术的 AI 写作软件&#xff0c;是内容生产领域新兴工具&…...

掌握Pwndbg调试器:从入门到精通的界面定制与配置指南

掌握Pwndbg调试器&#xff1a;从入门到精通的界面定制与配置指南 【免费下载链接】pwndbg Exploit Development and Reverse Engineering with GDB & LLDB Made Easy 项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg Pwndbg作为GDB和LLDB的增强扩展&#…...