简单的开始
- #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/archive/text_oarchive.hpp 和 boost/archive/text_iarchive.hpp 这两个文件。
- 为需要序列化的类添加一个template<class Archive> void serialize(Archive & ar, const unsigned int version)的模版成员函数。
- 如果需要对象中包含私有成员的话,需要把boost::serialization::access类声明为友元。
- 在主函数中,创建一个输出文件流对象, 使用这个对象构造一个text_oarchive对象,然后就可以使用<<操作符来输出对象了。
- 最后,同样的,使用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:
- ...
- };
- 包含boost/serialization/base_object.hpp头文件
- 在serialize模版函数中,使用ar & boost::serialization::base_object<父类>(*this)这样的语法来保存父类的数据,不能直接调用父类的serialize函数
STL容器
- // Serialization中特定的头文件,在list.hpp中已经包含了stl的list头文件
- #include <boost/serialization/list.hpp>
- Class A
- {
- ...
- list<int> list;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & list;
- }
- ...
- }
数组和指针
- Class A
- {
- ...
- int a[10];
- int *b
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & a;
- ar & b;
- }
- ...
- }
其他的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
oost::serialization 基于 boost::archive 来完成任意复杂数据结构的序列化,boost::archive提供两个实现类来完成序列化、反序列化操
作:
boost::archive::text_oarchive 序列化数据,也称为:输出、保存(save)
boost::archive::text_iarchive 反序列化数据,也称为:输入、载入(load)
&操作符
序列化操作使用 << 或者 & 操作符将数据存入text_oarchive中:
ar << data;
ar & data;
反序列化操作使用 >> 或者 & 操作符从text_iarchive中读取数据:
ar >> data;
ar & data;
为什么要引入&操作符?很简单,&操作符可以同时用于序列化和反序列化操作,这样就只需要提供一个 serialize 模板函数就可以同时用于两种
操作,具体执行哪种由ar的类型(模版参数类型)决定;如果ar是text_oarchive类型则是序列化,如果ar是text_iarchive类型则是反序列化。
serialize模版函数
基础简单数据类型直接使用&操作符就行了,class类型数据需要自定义serialize模板函数来序列化对象,序列化时serialize函数会被自动调用
。
有两种方式来给class添加serialize接口,一种是成员函数方式(intrusive),另一种是非成员函数方式(non-intrusive)。这两种方式各有
利弊:non-intrusive方式虽然不用修改class的定义,但要求class数据成员的访问属性为public,不过可以通过声明函数为friend来解决这个
问题。
成员函数方式(intrusive)
1 /**
2 * GPS坐标点
3 */
4 class gps_position
5 {
6 private:
7 friend class boost::serialization::access;
8
9 //intrusive方式,该成员函数同时用于序列化和反序列化操作
10 template<class Archive>
11 void serialize(Archive & ar, const unsigned int version)
12 {
13 ar & degrees & minutes & seconds;
14 }
15
16 int degrees;
17 int minutes;
18 float seconds;
19
20 public:
21 gps_position(){};
22 gps_position(int d, int m, float s) :
23 degrees(d), minutes(m), seconds(s)
24 {}
25 };
非成员函数方式(non-intrusive)
1 /**
2 * GPS坐标点
3 */
4 class gps_position
5 {
6 //non-intrusive方式,定义友元模版函数
7 template<class Archive>
8 friend void serialize(Archive& ar, gps_position& g, const unsigned int version)
9 {
10 ar & g.degrees & g.minutes & g.seconds;
11 }
12
13
14 private:
15 int degrees;
16 int minutes;
17 float seconds;
18
19 public:
20 gps_position(){};
21 gps_position(int d, int m, float s) :
22 degrees(d), minutes(m), seconds(s)
23 {}
24 };
类成员序列化
对类进行序列化要求所涉及的数据成员必须是可序列化的,即为:简单数据类型(POD)、数组类型、STL容器、或者实现了serialize接口的用户
类。一个复合类类型实现了serialize接口后,就只需要将该类看做一个整体传给&操作符进行序列化,&操作符在序列化其数据成员时会自动调用
相应的serialize接口进行处理。
1 /**
2 * bus_stop类
3 */
4 class bus_stop
5 {
6 friend class boost::serialization::access;
7
8 //只要数据成员类型是可序列化的就可以使用&操作符进行处理
9 //可序列化的类型包括:基础的简单数据类型、数组类型、STL容器、或者实现了serialize接口的类
10 template<class Archive>
11 void serialize(Archive & ar, const unsigned int version)
12 {
13 ar & latitude & longitude;
14 }
15
16 gps_position latitude; //serializable members
17 gps_position longitude;
18
19 protected:
20 bus_stop(const gps_position & lat_, const gps_position & long_) :
21 latitude(lat_), longitude(long_)
22 {}
23
24 public:
25 bus_stop(){}
26
27 virtual ~bus_stop(){}
28 };
编译程序
编译程序时需要带上库:-lboost_serialization