Archive

An archive is a sequence of bytes that represented serialized C++ objects. Objects can be added to an archive to serialize them and then later loaded from the archive.

1. boost::archive::text_iarchive

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <fstream> using namespace boost::archive; void save()
{
std::ofstream file("archive.txt");
text_oarchive oa{file};
int i = ;
oa << i;
} void load()
{
std::ifstream file("archive.txt");
text_iarchive ia{file};
int i = ;
ia >> i;
std::cout << i << std::endl;
} int main()
{
save();
load();
return ;
}

The class boost::archive::text_oarchive serializes data as a text stream, and the class boost::archive::text_iarchive restores data from such a text stream. Constructors of archives expect an input or output stream as a parameter. The stream is used to serialize or restore data.

2. serializing with a stringstream

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream> using namespace boost::archive; std::stringstream ss; void save()
{
text_oarchive oa{ss};
int i = ;
oa << i;
} void load()
{
text_iarchive ia{ss};
int i = ;
ia >> i;
std::cout << i << std::endl;
} int main()
{
save();
load();
return ;
}

output: 1

3. user-defined types with a member function

#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{};
oa << a;
} void load()
{
text_iarchive ia(ss);
animal a;
ia >> a;
std::cout << a.legs() << std::endl;
} int main()
{
save();
load();
return ;
}

In order to serialize objects of user-defined types, you must define the member function serialize(). This function is called when the object is serialized to or restored from a byte stream.

serialize() is automatically called any time an object is serialized or restored.

4. serializing with a free-standing function and serializing strings

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <iostream>
#include <sstream>
#include <string>
#include <utility> using namespace boost::archive; std::stringstream ss; class animal
{
public:
animal() = default;
animal(int legs, std::string name) :
legs_{legs}, name_{std::move(name)} {}
int legs() const { return legs_; }
const std::string &name() const { return name_; } private:
friend class boost::serialization::access; template <typename Archive>
friend void serialize(Archive &ar, animal &a, const unsigned int version); int legs_;
std::string name_;
}; template <typename Archive>
void serialize(Archive &ar, animal &a, const unsigned int version)
{
ar & a.legs_;
ar & a.name_;
} void save()
{
text_oarchive oa{ss};
animal a{, "cat"};
oa << a;
} void load()
{
text_iarchive ia{ss};
animal a;
ia >> a;
std::cout << a.legs() << std::endl;
std::cout << a.name() << std::endl;
} int main()
{
save();
load();
return ;
}

a member variable of type std::string, in order to serialize this member variable. the header file boost/serialization/string.hpp must be included to provide the appropriate free-standing function serialize().

Pointers and References

1. serializing pointers

#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();
oa << a;
std::cout << std::hex << a << std::endl;
delete a;
} void load()
{
boost::archive::text_iarchive ia(ss);
animal *a;
ia >> a;
std::cout << std::hex << a << std::endl;
std::cout << std::dec << a->legs() << std::endl;
delete a;
} int main()
{
save();
load();
return ;
}

Boost.Serialization automatically serializes the object referenced by a and not the address of the object.

If the archive is restored, a will not necessarily contain the same address. A new object is created and its address is assigned to a instead. Boost.Serialization only guarantees that the object is the same as the one serialized, not that its address is the same.

2 serializing smart pointers

#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() << std::endl;
} int main()
{
save();
load();
return ;
}

uses the smart pointer boost::scoped_ptr to manage a dynamically allocated object of type animal. Include the header file boost/serialization/scoped_ptr.hpp to serialize such a pointer. To serialize a smart pointer of type boost::shared_ptr, use the header file boost/serialization/shared_ptr.hpp.

3. serializing references

#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();
animal &r = a;
oa << r;
} void load()
{
text_iarchive ia(ss);
animal a;
animal &r = a;
ia >> r;
std::cout << r.legs() << std::endl;
} int main()
{
save();
load();
}

Serialization of Class Hierarchy Objects

Derived classes must access the function boost::serialization::base_object() inside the member function serialize() to serialize objects based on class hierarchies. This function guarantees that inherited member variables of base classes are correctly serialized.

1. serializing derived classes correctly

#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_;
}; class bird : public animal
{
public:
bird() = default;
bird(int legs, bool can_fly) :
animal(legs), can_fly_{can_fly} {}
bool can_fly() const { return can_fly_; } private:
friend class boost::serialization::access; template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<animal>(*this);
ar & can_fly_;
} bool can_fly_;
}; void save()
{
text_oarchive oa(ss);
bird penguin(, false);
oa << penguin;
} void load()
{
text_iarchive ia(ss);
bird penguin;
ia >> penguin;
std::cout << penguin.legs() << '\n';
std::cout << std::boolalpha << penguin.can_fly() << '\n';
} int main()
{
save();
load();
return ;
}

Inherited member variables are serialized by accessing the base class inside the member function serialize() of the derived class and calling boost::serialization::base_object(). You must use this function rather than, for example, static_cast because only boost::serialization::base_object() ensures correct serialization

2. registering derived classes statically with BOOST_CLASS_EXPORT

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
#include <iostream>
#include <sstream> using namespace boost::archive; std::stringstream ss; class animal
{
public:
animal() = default;
animal(int legs) : legs_(legs) {}
virtual int legs() const { return legs_; }
virtual ~animal() = default; private:
friend class boost::serialization::access; template <typename Archive>
void serialize(Archive &ar, const unsigned int version) { ar & legs_; } int legs_;
}; class bird : public animal
{
public:
bird() = default;
bird(int legs, bool can_fly) :
animal{legs}, can_fly_(can_fly) {}
bool can_fly() const { return can_fly_; } private:
friend class boost::serialization::access; template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<animal>(*this);
ar & can_fly_;
} bool can_fly_;
}; BOOST_CLASS_EXPORT(bird) void save()
{
text_oarchive oa(ss);
animal *a = new bird(, false);
oa << a;
delete a;
} void load()
{
text_iarchive ia(ss);
animal *a;
ia >> a;
std::cout << a->legs() << '\n';
delete a;
} int main()
{
save();
load();
return ;
}

To have Boost.Serialization recognize that an object of type bird must be serialized, even though the pointer is of type animal*, the class bird needs to be declared. This is done using the macro BOOST_CLASS_EXPORT, which is defined in boost/serialization/export.hpp. Because the type bird does not appear in the pointer definition, Boost.Serialization cannot serialize an object of type bird correctly without the macro.

The macro BOOST_CLASS_EXPORT must be used if objects of derived classes are to be serialized using a pointer to their corresponding base class. A disadvantage of BOOST_CLASS_EXPORT is that, because of static registration, classes can be registered that may not be used for serialization at all.

3. register_type()

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
#include <iostream>
#include <sstream> std::stringstream ss; class animal
{
public:
animal() = default;
animal(int legs) : legs_(legs) {}
virtual int legs() const { return legs_; }
virtual ~animal() = default; private:
friend class boost::serialization::access; template <typename Archive>
void serialize(Archive &ar, const unsigned int version) { ar & legs_; } int legs_;
}; class bird : public animal
{
public:
bird() = default;
bird(int legs, bool can_fly) :
animal{legs}, can_fly_(can_fly) {}
bool can_fly() const { return can_fly_; } private:
friend class boost::serialization::access; template <typename Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<animal>(*this);
ar & can_fly_;
} bool can_fly_;
}; void save()
{
boost::archive::text_oarchive oa(ss);
oa.register_type<bird>();
animal *a = new bird(, false);
oa << a;
delete a;
} void load()
{
boost::archive::text_iarchive ia(ss);
ia.register_type<bird>();
animal *a;
ia >> a;
std::cout << a->legs() << std::endl;
delete a;
} int main()
{
save();
load();
return ;
}

The type to be registered is passed as a template parameter. Note that register_type() must be called both in save() and load().

The advantage of register_type() is that only classes used for serialization must be registered. For example, when developing a library, one does not know which classes a developer may use for serialization later. While the macro BOOST_CLASS_EXPORT makes this easy, it may register types that are not going to be used for serialization.

boost serialization的更多相关文章

  1. 如何用boost::serialization去序列化派生模板类(续)

    在 如何用boost::serialization去序列化派生模板类这篇文章中,介绍了序列化派生类模板类, 在写測试用例时一直出现编译错误,调了非常久也没跳出来,今天偶然试了一下...竟然调了出来. ...

  2. 最经常使用的两种C++序列化方案的使用心得(protobuf和boost serialization)

    导读 1. 什么是序列化? 2. 为什么要序列化?优点在哪里? 3. C++对象序列化的四种方法 4. 最经常使用的两种序列化方案使用心得 正文 1. 什么是序列化? 程序猿在编写应用程序的时候往往须 ...

  3. 最常用的两种C++序列化方案的使用心得(protobuf和boost serialization)

    导读 1. 什么是序列化? 2. 为什么要序列化?好处在哪里? 3. C++对象序列化的四种方法 4. 最常用的两种序列化方案使用心得 正文 1. 什么是序列化? 程序员在编写应用程序的时候往往需要将 ...

  4. boost::serialization 用基类指针转存派生类(错误多多,一波三折)

    boost::serialization 也支持c++的多态,这样我们就能够通过使用基类的指针来转存派生类, 我们接着上一篇( boost::serialization(2)序列化基类 )的样例来看: ...

  5. :“boost/serialization/string.hpp”: No such file or directory 错误

    主要原因是没有安装和配置boost库. 解决:http://www.programlife.net/boost-compile-and-config.html

  6. Boost的Serialization和SmartPoint搭配使用

    准确来说,这篇博文并不是译文,而是一篇某个网页中代码改写而来.原文章中的代码存在几处严重错误,网页又不提供留言功能(不是没有而是一个没有留言功能的留言板).4年过去了,作者对这些错误不更正让人无法接受 ...

  7. 【boost】使用serialization库序列化子类

    boost.serialization库是一个非常强大又易用的序列化库,用于对象的保存与持久化等. 使用base_object可以在序列化子类的同时也序列化父类,以此获得足够的信息来从文件或网络数据中 ...

  8. C++ | boost库 类的序列化

    是的,这是今年的情人节,一篇还在研究怎么用的文章,文结的时候应该就用成功了. 恩,要有信心 神奇的分割线 不知何时装过boost库的header-only库, 所以ratslam中的boost是可以编 ...

  9. Linux上安装使用boost入门指导

    Data Mining Linux上安装使用boost入门指导 获得boost boost分布 只需要头文件的库 使用boost建立一个简单的程序 准备使用boost二进制文件库 把你的程序链接到bo ...

随机推荐

  1. What code you will get when you create a wcf library

    创建wcf服务库的时候,系统自动生成的代码 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”. [ServiceContract] publ ...

  2. HTML5 新属性的讲解

    1.选择器: 标签选择器: class选择器: id选择器: 后代选择器:div li div下所有li 子代选择器:div>li div的所有子一代 li 元素 交集选择器:div.class ...

  3. jajaj

    Docs » 第二章:字符串和文本 » 2.2 字符串开头或结尾匹配 Edit on GitHub 2.2 字符串开头或结尾匹配¶ 问题¶ 你需要通过指定的文本模式去检查字符串的开头或者结尾,比如文件 ...

  4. day30—使用Flexbox和CSS Grid实现高效布局实践

    转行学开发,代码100天——2018-04-15 (今天是代码开发的第30天,但是代码记录有些滞后,尽快补上.日后要严格执行,避免学习进度和内容相对滞后.) 今天,记录“前端大全”里分享的一篇关于利用 ...

  5. CentOS7.4伪分布式搭建 hadoop+zookeeper+hbase+opentsdb

    前言 由于hadoop和hbase都得想zookeeper注册,所以启动顺序为 zookeeper——>hadoop——>hbase,关闭顺序反之 一.前期准备 1.配置ip 进入文件编辑 ...

  6. JSP 定义行列数表单创建表格

    1.添加行数 .列数提交表单 <!doctype html> <html> <head> <title>setTable-发送表单</title& ...

  7. 页面跳转(包括vue路由)

    1.JS实现页面跳转 1.1 使用window.location的href属性跳转 window.location.href = 'http://www.baidu.com';此处window可以省略 ...

  8. jmeter动态修改线程组参数

    jmeter非gui模式修改线程属性进行性能测试 在使用JMeter进行性能测试自动化时,如果按照平常的非Gui模式就是脚本每次修改参数都需要在gui模式下修改保存之后,然后在非gui模式之后运行,这 ...

  9. Bootstrap 学习笔记12 轮播插件

    轮播插件: <!-- data-ride="carousel"自动播放 --> <div id="myCarousel" class=&quo ...

  10. Play with Chain 【HDU - 3487】【Splay+TLE讲解】

    题目链接 很好的一道题,用了三天多的时间,终于知道了我为什么T的原因,也知道了在Splay的同时该怎样子的节约时间,因为Splay本身就是大常数的O(N*logN),我们如果不在各种细节上节约时间,很 ...