C++ Boost Serialization 指针与引用序列化详解

叶初
叶初
发布时间:2026-10-15| 2人浏览过
原创

深入解析 C++ Boost.Serialization 库中指针与引用的序列化行为,通过原始指针、scoped_ptr 及引用类型的代码示例,阐明序列化的是对象内容而非地址,并说明其对 C++11 智能指针的支持现状。

核心机制:序列化对象而非地址

Boost.Serialization 库在处理指针和引用时遵循“序列化合约对象”的原则。由于指针仅存储内存地址,而该地址在不同进程或重启后的程序中将失效,直接序列化地址无实际意义。因此,当序列化指针或引用时,Boost.Serialization 会追溯其指向的实际对象并进行序列化;反序列化时,也会重新构造一个全新的对象实例。

实战操作与代码示例

第1步:使用原始指针进行序列化

目的:演示动态分配的普通对象如何通过指针被正确序列化与还原,验证反序列化后对象内容与原对象一致但地址不同。

关键逻辑:

  • 类内部需定义友元 boost::serialization::access 并重载 serialize 函数以告知库如何保存成员变量。
  • 使用 boost::archive::text_oarchive 写入,boost::archive::text_iarchive 读取。
  • 反序列化后,指针变量会被赋值为一个新分配对象的地址,必须手动管理内存以避免泄漏。

代码实现:

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream>

std::stringstream ss;

class animal
{
public:
  animal() = default;
  animal(int legs) : legs_{legs} {}
  int legs() const { return legs_; }
private:
  friend class boost::serialization::access;
  template <typename Archive>
  void serialize(Archive &ar, const unsigned int version) { ar & legs_; }
  int legs_;
};

void save()
{
  boost::archive::text_oarchive oa{ss};
  animal *a = new animal{4};
  oa << a;
  std::cout << std::hex << a << '\n';
  delete a;
}

void load()
{
  boost::archive::text_iarchive ia{ss};
  animal *a;
  ia >> a;
  std::cout << std::hex << a << '\n';
  std::cout << std::dec << a->legs() << '\n';
  delete a;
}

int main()
{
  save();
  load();
}

在此示例中,oa << a 触发了对 a 指向的 animal 对象的序列化。加载时,ia >> a 会创建一个全新的 animal 对象,并更新指针 a 指向该新地址。输出结果显示两次输出的十六进制地址不同,但 legs()

第2步:使用 scoped_ptr 智能指针进行序列化

目的:利用 Boost 提供的智能指针自动管理内存,简化序列化过程中的资源清理工作。

准备条件:包含头文件 <boost/serialization/scoped_ptr.hpp> 和 <boost/scoped_ptr.hpp>。

注意事项:Boost.Serialization 原生支持 boost::shared_ptr 时需包含 <boost/serialization/shared_ptr.hpp>。但对于 C++11 标准库中的 std::shared_ptr 和 std::unique_ptr,旧版 Boost.Serialization 并不直接支持,可能需要自定义特化或升级库版本。

代码实现:

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/scoped_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <iostream>
#include <sstream>

using namespace boost::archive;
std::stringstream ss;

class animal
{
public:
  animal() = default;
  animal(int legs) : legs_{legs} {}
  int legs() const { return legs_; }
private:
  friend class boost::serialization::access;
  template <typename Archive>
  void serialize(Archive &ar, const unsigned int version) { ar & legs_; }
  int legs_;
};

void save()
{
  text_oarchive oa{ss};
  boost::scoped_ptr<animal> a{new animal{4}};
  oa << a;
}

void load()
{
  text_iarchive ia{ss};
  boost::scoped_ptr<animal> a;
  ia >> a;
  std::cout << a->legs() << '\n';
}

int main()
{
  save();
  load();
}

使用 scoped_ptr 可以自动在作用域结束时释放内存,避免了手动 delete 的繁琐。关键在于类定义依然保持不变,序列化头文件的引入使得库能识别并正确处理智能指针类型。

第3步:使用引用进行序列化

目的:展示对局部对象引用的序列化过程,证明引用序列化本质上是对其绑定对象的序列化。

操作顺序:

  1. 定义本地对象 animal a{4}。
  2. 创建引用 animal &r = a。
  3. 将引用 r 传入存档对象。

代码实现:

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream>

using namespace boost::archive;
std::stringstream ss;

class animal
{
public:
  animal() = default;
  animal(int legs) : legs_{legs} {}
  int legs() const { return legs_; }
private:
  friend class boost::serialization::access;
  template <typename Archive>
  void serialize(Archive &ar, const unsigned int version) { ar & legs_; }
  int legs_;
};

void save()
{
  text_oarchive oa{ss};
  animal a{4};
  animal &r = a;
  oa << r;
}

void load()
{
  text_iarchive ia{ss};
  animal a;
  animal &r = a;
  ia >> r;
  std::cout << r.legs() << '\n';
}

int main()
{
  save();
  load();
}

引用 r 的序列化等同于对象 a 的序列化。加载时,ia >> r 会将数据填充到 load 函数中新创建的本地对象 a 中。这种方式适用于不需要转移所有权,仅需持久化对象状态的场景。

总结与排错建议

在进行 C++ Boost Serialization 开发时,需注意以下几点:

  • 内存管理:若使用原始指针,务必在序列化结束后检查是否需要在加载侧清理内存,尽管示例中展示了显式 delete,但在复杂架构中建议使用智能指针包裹以保安全。
  • C++11 兼容性:如需使用 std::shared_ptr,请确认所用 Boost 版本是否已整合对标准库智能指针的支持,否则需回退至 boost::shared_ptr 或编写自定义适配器。
  • 版本控制:在类中实现序列化接口时,注意 serialize 函数签名中的 version 参数,以便在未来修改数据结构时保持向后兼容。

以上就是 C++ Boost Serialization 库指针与引用序列化详细内容的解答,更多关于 C++ 数据存储与格式化的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。