Learning boost 1 Serialization

本文介绍Boost库中的序列化功能,包括基本序列化流程、继承情况下序列化子类的方法、序列化STL容器的方式以及如何处理数组和指针。此外还列举了多种不同格式的归档类。
简单的开始
Serialization的中文解释是“串行化” 、“序列化”或者“持久化” ,就是将内存中的对象保存到磁盘中,等到程序再次运行的时候再读取磁盘中的文件恢复原来的对象。下面来看一个简单的例子:
#include <fstream>
#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
class A
{
private:
    //为了能让串行化类库能够访问私有成员,所以要声明一个友元类
    friend class boost::serialization::access;
    //对象的数据
    int a;
    double b;
    //串行化的函数,这一个函数完成对象的保存与恢复
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & a;  //就是这么简单,也可以使用 ar<<a 这样的语法
        ar & b;
    }
public:
    A(int aa,double bb):a(aa),b(bb){}
    A(){}
    void print(){std::cout<<a<<' '<<b<<std::endl;}
};   
int main()
{
   std::ofstream fout("file.txt");//把对象写到file.txt文件中
   boost::archive::text_oarchive oa(fout);//文本的输出归档类,使用一个ostream来构造
   A obj(1,2.5);
   oa<<obj;//保存obj对象
   fout.close();//关闭文件
  
   std::ifstream fin("file.txt");
   boost::archive::text_iarchive ia(fin);//文本的输入归档类
   A newobj;
   ia>>newobj;//恢复到newobj对象
   newobj.print();
   fin.close();
   system("pause");
   return 0;
}
 
从上面可以看出,boost是使用text_oarchive和text_iarchive 类,来完成一个对象的序列化的。使用这两个类的步骤是:
1.      在源程序中包含boost/archive/text_oarchive.hpp 和 boost/archive/text_iarchive.hpp 这两个文件。
2.      为需要序列化的类添加一个template<class Archive> void serialize(Archive & ar, const unsigned int version)的模版成员函数。
3.      如果需要对象中包含私有成员的话,需要把boost::serialization::access类声明为友元。
4.      在主函数中,创建一个输出文件流对象, 使用这个对象构造一个text_oarchive对象,然后就可以使用<<操作符来输出对象了。
5.      最后,同样的,使用text_iarchive来恢复对象。
 
继承
如果要序列化一个子类的话,方法是不同的。例:
#include <boost/serialization/base_object.hpp> //一定要包含此头文件
class B:A
{
    friend class boost::serialization::access;
    char c;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<A>(*this);//注意这里
        ar & c;
    }
public:
    ...
};   
 
对子类进行序列化的步骤是:
1.      包含boost/serialization/base_object.hpp头文件
2.      在serialize模版函数中,使用ar & boost::serialization::base_object<父类>(*this)这样的语法来保存父类的数据,不能直接调用父类的serialize函数
 
STL容器
如果要序列化一个STL容器,要使用boost自带的头文件,不能直接#include<vector>
例如:
#include <boost/serialization/list.hpp>// Serialization中特定的头文件,在list.hpp中已经包含了stl的list头文件
Class A
{
 ...
 list<int> list;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
 {
      ar & list;
 }
...
}
在Serialization中,类似的头文件还有vector.hpp string.hpp set.hpp map.hpp slist.hpp等等。
 
数组和指针
对于数组和指针可以直接序列化,例:
Class A
{
 ...
 int a[10];
 int *b
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
 {
      ar & a;
      ar & b;
 }
...
}
 
其他的archive类
除了text_iarchive和text_oarchive之外,还有其他的archive类,可以把对象保存成不同格式的文件。
// a portable text archive
boost::archive::text_oarchive(ostream &s) // saving
boost::archive::text_iarchive(istream &s) // loading
 
// a portable text archive using a wide character stream
boost::archive::text_woarchive(wostream &s) // saving
boost::archive::text_wiarchive(wistream &s) // loading
 
// a non-portable native binary archive
boost::archive::binary_oarchive(ostream &s) // saving
boost::archive::binary_iarchive(istream &s) // loading
 
// a portable XML archive
boost::archive::xml_oarchive(ostream &s) // saving
boost::archive::xml_iarchive(istream &s) // loading
 
// a portable XML archive which uses wide characters - use for utf-8 output
boost::archive::xml_woarchive(wostream &s) // saving
boost::archive::xml_wiarchive(wistream &s) // loading
 
 

 
<think> 我们被要求提供关于boost.serialization的详细介绍。根据引用的内容,我们可以总结出以下要点: 1. Boost.Serialization是一个用于C++对象序列化和反序列化的库(引用[1])。 2. 它可以将对象转换为字节流,以便于传输和存储(引用[1])。 3. 支持侵入式和非侵入式两种方式(引用[3])。 4. 提供了对STL容器的序列化支持(引用[4])。 5. 提供了封装函数如`make_binary_object`和`make_array`用于处理二进制数据和数组(引用[2])。 现在,我们将根据这些信息详细介绍Boost.Serialization库。 # Boost.Serialization详细介绍 Boost.Serialization库是Boost库的一部分,用于实现C++对象的序列化和反序列化。序列化是将对象的状态信息转换为可以存储或传输的形式的过程,反序列化则是从存储格式中重新构建对象的过程。 ## 核心特性 1. **多种归档格式**:支持文本、二进制和XML等多种格式的归档(存储方式)。例如,文本归档使用`boost::archive::text_oarchive`和`boost::archive::text_iarchive`(引用[4])。 2. **侵入式与非侵入式**: - **侵入式**:在需要序列化的类中定义一个`serialize`成员函数(引用[3])。 - **非侵入式**:在不修改类定义的情况下,在外部定义序列化函数(引用[3])。 3. **支持标准库容器**:可以直接序列化STL容器,如`std::list`、`std::vector`等(引用[4])。 4. **指针和引用处理**:能够处理指针和引用,包括处理多态对象和循环引用。 5. **版本控制**:支持版本管理,当类的结构发生变化时,可以通过版本号来控制序列化与反序列化的兼容性。 ## 基本用法 ### 侵入式序列化 在类内部定义`serialize`函数模板: ```cpp #include <boost/serialization/serialization.hpp> class MyClass { private: friend class boost::serialization::access; template <class Archive> void serialize(Archive & ar, const unsigned int version) { ar & member1; ar & member2; } int member1; double member2; public: // 构造函数等 }; ``` ### 非侵入式序列化 在类外部定义序列化函数: ```cpp namespace boost { namespace serialization { template<class Archive> void serialize(Archive & ar, MyClass & obj, const unsigned int version) { ar & obj.member1; ar & obj.member2; } } // namespace serialization } // namespace boost ``` ### 序列化到文件 以下示例展示了如何将对象序列化到文件并读回: ```cpp #include <fstream> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> void save(const MyClass& obj, const char* filename) { std::ofstream ofs(filename); boost::archive::text_oarchive oa(ofs); oa << obj; } void load(MyClass& obj, const char* filename) { std::ifstream ifs(filename); boost::archive::text_iarchive ia(ifs); ia >> obj; } ``` ### 序列化STL容器 Boost.Serialization提供了对STL容器的序列化支持。在使用时需要包含相应的头文件,例如`<boost/serialization/list.hpp>`(引用[4])。 ## 异常处理 在处理指针反序列化时,可能会遇到异常。例如,如果反序列化时无法分配内存或数据损坏,Boost.Serialization会抛出异常。因此,建议在反序列化操作中使用`try-catch`块来捕获可能的异常(引用[1])。 ## 二进制数据处理 对于原始二进制数据,可以使用`make_binary_object`函数。这个函数接受数据的指针和长度,并返回一个包装对象,该对象可以被序列化(引用[2])。 ```cpp char buffer[100]; // ... 填充buffer ... ar & make_binary_object(buffer, sizeof(buffer)); ``` 对于数组,使用`make_array`: ```cpp int array[10]; // ... 初始化数组 ... ar & make_array(array, 10); ``` ## 总结 Boost.Serialization是一个功能强大且灵活的序列化库,支持多种数据格式和自定义类型序列化。通过侵入式或非侵入式的方式,可以轻松实现对象的持久化。同时,它还提供了对STL容器、指针和二进制数据的支持。 在使用指针序列化时,需要注意异常处理和内存管理,以避免内存泄漏和其他安全问题。 §§相关问题§§ 1. Boost.Serialization支持哪些归档格式? 2. 如何处理多态对象的序列化与反序列化? 3. Boost.Serialization如何实现版本控制? </think> ### Boost.Serialization 详细介绍 Boost.SerializationBoost C++ 库集合中的核心组件,专为**对象序列化与反序列化**设计。它提供了一种跨平台的机制,可将 C++ 对象转化为字节流(序列化),并能从字节流重建原始对象(反序列化)。以下是其核心特性与工作机制: --- #### 一、核心功能 1. **数据持久化** 将对象状态转换为字节流,支持: - 文本格式(可读性高) - 二进制格式(存储高效) - XML 格式(结构化存储) 2. **跨环境传输** 序列化后的数据可通过网络传输、文件存储或数据库保存,在异构系统中重建对象[^1]。 3. **指针与多态支持** 支持智能指针(如 `shared_ptr`)和多态对象的序列化,自动处理对象关系和内存管理[^1]。 --- #### 二、序列化方式 1. **侵入式(修改类定义)** 在类内部定义 `serialize` 函数模板: ```cpp class MyClass { friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int version) { ar & data_member; // 序列化成员变量 } int data_member; }; ``` 2. **非侵入式(不修改类)** 在外部命名空间定义序列化函数[^3]: ```cpp namespace boost { namespace serialization { template<class Archive> void serialize(Archive& ar, MyClass& obj, unsigned int version) { ar & obj.data_member; } }} ``` --- #### 三、关键技术特性 1. **STL 容器支持** 内置对 `std::vector`, `std::list`, `std::map` 等容器的序列化支持[^4]: ```cpp #include <boost/serialization/list.hpp> class A { std::list<int> data; // ... serialize 函数内直接操作容器 }; ``` 2. **二进制数据处理** 专用函数处理原始二进制数据: - `make_binary_object()`:序列化无结构的二进制块(如图像数据)[^2] - `make_array()`:序列化数组(保留元素内存布局) 3. **版本控制** 通过 `version` 参数实现向后兼容: ```cpp template<class Archive> void serialize(Archive& ar, const unsigned int version) { if (version > 0) ar & new_member; // 新增字段 ``` 声明版本号:`BOOST_CLASS_VERSION(MyClass, 2)` --- #### 四、典型使用流程 ```cpp #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> void save_object(const MyClass& obj) { std::ofstream fout("data.txt"); boost::archive::text_oarchive oa(fout); oa << obj; // 序列化到文件 } void load_object(MyClass& obj) { std::ifstream fin("data.txt"); boost::archive::text_iarchive ia(fin); ia >> obj; // 从文件反序列化 } ``` --- #### 五、异常处理机制 - **指针反序列化安全**:内存分配失败时抛出 `boost::archive::archive_exception`[^1] - **自定义异常处理**: ```cpp try { ia >> obj_ptr; // 尝试反序列化指针 } catch (const boost::archive::archive_exception& e) { // 处理内存不足或数据损坏 } ``` --- #### 六、适用场景 1. 分布式系统中的对象传输 2. 游戏状态保存/加载 3. 科学计算数据持久化 4. 跨平台配置存储(XML 格式) 5. 网络通信中的参数传递
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值