0

0

c++中如何将对象序列化_c++对象持久化存储的常用方案【详解】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-17 13:03:12

|

604人浏览过

|

来源于php中文网

原创

直接用 std::ofstream 写 sizeof(obj) 会出错,因为 C++ 对象含指针、虚表或 STL 成员时,二进制拷贝仅保存地址而非数据,反序列化后导致崩溃;POD 结构若含 std::string 等仍不安全。

c++中如何将对象序列化_c++对象持久化存储的常用方案【详解】

为什么 std::ofstream 直接写 sizeof(obj) 会出错

因为 C++ 对象通常含指针、虚函数表、引用成员或非 POD 类型子对象,memcpy 级别二进制拷贝会把内存地址原样保存,反序列化时读出来的指针指向无效地址,程序崩溃或数据错乱。即使对象是 POD(如纯 struct),若含 std::stringstd::vector 等标准容器,其内部指针也不会被正确重建。

boost::serialization 实现可移植的类级序列化

这是最成熟、支持 C++ 原生语义的方案,能自动处理继承、多态、指针共享、STL 容器等复杂情况。前提是类需显式声明序列化逻辑,且所有依赖类型也支持该库。

  • 必须为待序列化类添加 serialize 成员函数,或特化 boost::serialization::serialize 模板
  • 使用 BOOST_SERIALIZATION_SPLIT_MEMBER() 可分离 save/load 逻辑
  • 归档类型选 boost::archive::binary_oarchive(紧凑)或 boost::archive::text_oarchive(可读、跨平台)
  • 编译需链接 -lboost_serialization,头文件为
#include 
#include 
#include 

struct Person {
    std::string name;
    int age;
    template
    void serialize(Archive& ar, const unsigned int version) {
        ar & name & age;
    }
};

// 序列化
std::ofstream ofs("person.txt");
boost::archive::text_oarchive oa(ofs);
Person p{"Alice", 30};
oa << p;

// 反序列化
std::ifstream ifs("person.txt");
boost::archive::text_iarchive ia(ifs);
Person p2;
ia >> p2;

轻量替代:手动实现 to_json() / from_json()(基于 nlohmann/json)

当目标是配置、状态快照或跨语言交互时,JSON 是更安全、易调试的选择。nlohmann/json 支持直接操作 struct,但需配合 NLOHMANN_DEFINE_TYPE_INTRUSIVENLOHMANN_DEFINE_TYPE_NON_INTRUSIVE 宏。

  • 不支持虚函数、裸指针、循环引用,但对普通业务对象足够健壮
  • 生成文本可读,便于人工检查和 patch,也方便 Web API 复用
  • 编译零依赖,头文件即用,但需 C++17 起支持结构化绑定
  • 注意 std::chrono::time_pointstd::optional 等需额外提供转换逻辑
#include 
using json = nlohmann::json;

struct Config {
    std::string host;
    int port;
    std::vector endpoints;
};

NLOHMANN_DEFINE_TYPE_INTRUSIVE(Config, host, port, endpoints)

// 序列化
Config cfg{"localhost", 8080, {"api/v1", "health"}};
json j = cfg;
std::ofstream("config.json") << j.dump(2);

// 反序列化
std::ifstream f("config.json");
json j2;
f >> j2;
Config cfg2 = j2.get();

生产环境慎用:自定义二进制格式 + reinterpret_cast

仅适用于完全可控的 POD 结构体(如网络协议包、GPU 数据块)、固定 ABI、同版本同架构部署。一旦类加字段、改顺序、换编译器,就无法兼容。

PaperAiBye
PaperAiBye

支持近30多种语言降ai降重,并且支持多种语言免费测句子的ai率,支持英文aigc报告等

下载

立即学习C++免费学习笔记(深入)”;

  • 必须用 #pragma pack(1)alignas 消除填充字节
  • 整数字段要统一字节序(推荐 htons/ntohl),否则跨平台失效
  • 字符串不能存 char*,得存长度+字符数组,或改用固定长 std::array
  • 没有版本管理能力,升级字段需额外加 magic number 和 size header

真正需要高性能二进制序列化的场景,建议用 Protocol Buffers 或 FlatBuffers —— 它们生成 C++ 代码、带 schema 版本控制、支持向后兼容,比手写更可靠。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

412

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

533

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

309

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

74

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

318

2023.08.02

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.09.04

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

40

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.3万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号