下面看一个简单的例子。
Boost.Serialization 提供了多个归档类,如 类,它定义在 boost/archive/text_oarchive.hpp
文件中。 boost::archive::text_oarchive
,可将对象序列化为文本流。 上面的应用程序将 22 serialization::archive 5 1
写出到标准输出流。
可见, boost::archive::textoarchive
类型的对象 _oa 可以用来像流 (stream) 一样通过 <<
来序列化对象。 尽管如此,归档也不能被认为是可以存储任何数据的常规的流。 为了以后恢复数据,必须以相同的顺序使用和先前存储时用的一样的数据类型。 下面的例子序列化和恢复了 int
类型的变量。
- #include <boost/archive/text_oarchive.hpp>
- #include <boost/archive/text_iarchive.hpp>
- #include <iostream>
- #include <fstream>
- void save()
- {
- std::ofstream file("archiv.txt");
- boost::archive::text_oarchive oa(file);
- int i = 1;
- oa << i;
- }
- void load()
- {
- std::ifstream file("archiv.txt");
- boost::archive::text_iarchive ia(file);
- int i = 0;
- ia >> i;
- std::cout << i << std::endl;
- }
- int main()
- {
- save();
- load();
- }
当 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;
- 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 能够访问到这个函数。
有些情况下需要添加 serialize()
函数却不能修改现有的类。 比如,对于来自 C++ 标准库或其他库的类就是这样的。
为了序列化那些不能被修改的数据类型,要定义一个单独的函数 serialize()
,如上面的例子所示。 这个函数需要相应的数据类型的引用作为它的第二个参数。
不过还好,Boost.Serialization 为许多C++标准库的类提供了 serialize()
函数。 为了序列化基于 C++ 标准库的类,需要包含额外的头文件。
- #include <boost/archive/text_oarchive.hpp>
- #include <boost/archive/text_iarchive.hpp>
- #include <boost/serialization/string.hpp>
- #include <iostream>
- #include <sstream>
- #include <string>
- std::stringstream ss;
- class person
- {
- public:
- person()
- {
- }
- person(int age, const std::string &name)
- {
- }
- int age() const
- {
- return age_;
- }
- std::string name() const
- {
- return name_;
- }
- private:
- friend class boost::serialization::access;
- template <typename Archive>
- friend void serialize(Archive &ar, person &p, const unsigned int version);
- int age_;
- std::string name_;
- };
- template <typename Archive>
- void serialize(Archive &ar, person &p, const unsigned int version)
- {
- ar & p.age_;
- ar & p.name_;
- }
- void save()
- {
- boost::archive::text_oarchive oa(ss);
- person p(31, "Boris");
- oa << p;
- }
- void load()
- {
- boost::archive::text_iarchive ia(ss);
- person p;
- ia >> p;
- std::cout << p.age() << std::endl;
- std::cout << p.name() << std::endl;
- }
- int main()
- {
- save();
- load();
- }
这个例子扩展了 person
类,增加了 std::string
类型的名称变量,为了序列化这个属性property, the header file boost/serialization/string.hpp
头文件必须包含,它提供了合适的单独的 serialize ()
函数。
正如前面所提到的, Boost.Serialization 为许多 C++ 标准库类定义了 函数。 这些都定义在和 C++ 标准库头文件名称相对应的头文件中。 为了序列化 std::string
类型的对象,必须包含 boost/serialization/string.hpp
头文件。 为了序列化 std::vector
类型的对象,必须包含 boost/serialization/vector.hpp
头文件。 于是在给定的场合中应该包含哪个头文件就显而易见了。
还有一个 serialize ()
函数的参数,到目前为止我们一直忽略没谈到,那就是 version 。 如果归档需要向前兼容,以支持给定应用程序的未来版本,那么这个参数就是有意义的。 接下来的例子考虑到 person
类的归档需要向前兼容。由于 person
的原始版本没有包含任何名称,新版本的 person
应该能够处理不带名称的旧的归档。
BOOST_CLASS_VERSION
宏用来指定类的版本号。 上面例子中 person
类的版本号设置为1。 如果没有使用 BOOST_CLASS_VERSION
, 版本号缺省是0。