Learning boost 1 Serialization

Learning boost (1)

Serialization

简单的开始

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_oarchivetext_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中已经包含了stllist头文件

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_iarchivetext_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. 网络通信中的参数传递
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值