博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

boost 序列化

Posted on 2015-11-11 12:46  bw_0927  阅读(284)  评论(0)    收藏  举报

http://zh.highscore.de/cpp/boost/serialization.html

  • 基本类型

当 boost::archive::text_oarchive 被用来把数据序列化为文本流, boost::archive::text_iarchive 就用来从文本流恢复数据。 为了使用这些类,必须包含 boost/archive/text_iarchive.hpp 头文件。

归档的构造函数需要一个输入或者输出流作为参数。 流分别用来序列化或恢复数据。 虽然上面的应用程序使用了一个文件流,其他流,如 stringstream 流也是可以的。

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

std::stringstream ss; 

void save() 
{ 
  boost::archive::text_oarchive oa(ss); 
  int i = 1; 
  oa << i; 
} 

void load() 
{ 
  boost::archive::text_iarchive ia(ss); 
  int i = 0; 
  ia >> i; 
  std::cout << i << std::endl; 
} 

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

  • 自定义类型
#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <iostream> 
#include <sstream> 

std::stringstream ss; 

class person 
{ 
public: 
  person() 
  { 
  } 

  person(int age) 
    : age_(age) 
  { 
  } 

  int age() const 
  { 
    return age_; 
  } 

private: 
  friend class boost::serialization::access; 

  template <typename Archive> 
  void serialize(Archive &ar, const unsigned int version) 
  { 
    ar & age_; 
  } 

  int age_; 
}; 

void save() 
{ 
  boost::archive::text_oarchive oa(ss); 
  person p(31); 
  oa << p; 
} 

void load() 
{ 
  boost::archive::text_iarchive ia(ss); 
  person p; 
  ia >> p; 
  std::cout << p.age() << std::endl; 
} 

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

为了序列化用户定义类型的对话, serialize() 函数必须定义,它在对象序列化或从字节流中恢复是被调用。 由于 serialize () 函数既用来序列化又用来恢复数据, Boost.Serialization 除了 << 和 >> 之外还提供了 & 操作符。如果使用这个操作符,就不再需要在 serialize() 函数中区分是序列化和恢复了。

serialize () 在对象序列化或恢复时自动调用。它应从来不被明确地调用,所以应生命为私有的。 这样的话, boost::serialization::access 类必须被声明为友元,以允许 Boost.Serialization 能够访问到这个函数。

  • c++现在库类型

有些情况下需要添加 serialize() 函数却不能修改现有的类。 比如,对于来自 C++ 标准库或其他库的类就是这样的。

  • 不可修改的自定义类型

为了序列化那些不能被修改的数据类型,要定义一个单独的函数 serialize(),如上面的例子所示。 这个函数需要相应的数据类型的引用作为它的第二个参数。

 

 

如果要被序列化的数据类型中含有不能经由公有函数访问的私有属性,事情就变得复杂了。 在这种情况下,该数据列席就需要修改。 在上面应用程序中的 serialize () 函数如果不声明为 friend ,就不能访问 age_ 属性。

不过还好,Boost.Serialization 为许多C++标准库的类提供了 serialize() 函数。 为了序列化基于 C++ 标准库的类,需要包含额外的头文件。

正如前面所提到的, Boost.Serialization 为许多 C++ 标准库类定义了 serialize () 函数。 这些都定义在和 C++ 标准库头文件名称相对应的头文件中。 为了序列化 std::string 类型的对象,必须包含 boost/serialization/string.hpp 头文件。 为了序列化 std::vector 类型的对象,必须包含 boost/serialization/vector.hpp 头文件。 于是在给定的场合中应该包含哪个头文件就显而易见了。

 

  • 向前兼容

 version 。 如果归档需要向前兼容,以支持给定应用程序的未来版本,那么这个参数就是有意义的。

BOOST_CLASS_VERSION 宏用来指定类的版本号。

 

  • 指针和引用

由于指针存储对象的地址,序列化对象的地址没有什么意义,而是在序列化指针和引用时,对象的引用被自动地序列化。

Boost.Serialization 自动地通过 的引用序列化对象本身而不是对象的地址。Boost.Serialization 只保证对象和之前序列化的对象相同,而不是地址相同。

Boost.Serialization 还能没有任何问题地序列化引用。 就像指针一样,引用对象被自动地序列化。

由于新式的 C++ 在动态分配内存有关的地方使用 智能指针 (smart pointers) , Boost.Serialization 对此也提供了相应的支持。