对象序列化是项目中最经常看到的场景,因此实现该功能的库也有很多,如:thrift、protobuf、avro,但我觉得这些库都太过沉重,因为他们还提供了rpc的功能,如果只是单纯做对象序列化,boost serialization是个不错的选择,以下boost serialization简称BS。
一、代码目录
1.$BOOST_HOME/archive存档方式类目录
类型 | 普通字节 | 宽字节 |
---|---|---|
二进制 | binary_iarchive.hpp binary_oarchive.hpp | binary_wiarchive.hpp binary_woarchive.hpp |
文本 | text_iarchive.hpp text_oarchive.hpp | text_wiarchive.hpp text_woarchive.hpp |
xml | xml_iarchive.hpp xml_oarchive.hpp | xml_wiarchive.hpp xml_woarchive.hpp |
2.$BOOST_HOME/serialization 序列化数据类型目录
目前BS基本上几乎支持了所有的C++数据类型,还包括指针、数组等,并且也支持了stl的容器,但要包含相关头文件。
vector.hpp支持vector的序列化
list.hpp支持list的序列化
deque.hpp支持deque的序列化
map.hpp支持map的序列化
hash_map.hpp支持hash_map的序列化
等等...
除了stl的容器,也支持boost的相关容器,如array.hpp
二、序列化类实现
1.置入式实现
- #include <fstream>
- // 文本方式存档
- #include <boost/archive/text_oarchive.hpp>
- #include <boost/archive/text_iarchive.hpp>
- /
- // gps coordinate
- //
- // illustrates serialization for a simple type
- //
- class gps_position
- {
- private:
- friend class boost::serialization::access;//置入式
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & degrees;//序列化或反序列化&操作符比>>和<<更为方便
- ar & minutes;
- ar & seconds;
- }
- int degrees;
- int minutes;
- float seconds;
- public:
- gps_position(){};
- gps_position(int d, int m, float s) :
- degrees(d), minutes(m), seconds(s)
- {}
- };
- int main() {
- std::fstream ofs("filename");
- // create class instance
- const gps_position g(35, 59, 24.567f);
- // save data to archive
- {
- boost::archive::text_oarchive oa(ofs);
- oa << g;
- }
- // ... some time later restore the class instance to its orginal state
- gps_position newg;
- {
- std::fstream ifs("filename");
- boost::archive::text_iarchive ia(ifs);
- ia >> newg;
- }
- return 0;
- }
- #include <boost/archive/text_oarchive.hpp>
- #include <boost/archive/text_iarchive.hpp>
- class gps_position
- {
- public:
- int degrees;
- int minutes;
- float seconds;
- gps_position(){};
- gps_position(int d, int m, float s) :
- degrees(d), minutes(m), seconds(s)
- {}
- };
- namespace boost {
- namespace serialization {
- template<class Archive>
- void serialize(Archive & ar, gps_position & g, const unsigned int version)//必须包含在boost::serialization名字空间下
- {
- ar & g.degrees;
- ar & g.minutes;
- ar & g.seconds;
- }
- } // namespace serialization
- } // namespace boost
3.可以序列化类对象,但被序列化的类必须实现序列化函数
- class bus_stop
- {
- friend class boost::serialization::access;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & latitude;
- ar & longitude;
- }
- gps_position latitude;
- gps_position longitude;
- protected:
- bus_stop(const gps_position & lat_, const gps_position & long_) :
- latitude(lat_), longitude(long_)
- {}
- public:
- bus_stop(){}
- // See item # 14 in Effective C++ by Scott Meyers.
- // re non-virtual destructors in base classes.
- virtual ~bus_stop(){}
- };
4.继承关系的序列化
- #include <boost/serialization/base_object.hpp>//必须包含这个头文件
- class bus_stop_corner : public bus_stop
- {
- friend class boost::serialization::access;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- // serialize base class information
- ar & boost::serialization::base_object<bus_stop>(*this);//序列化基类
- ar & street1;
- ar & street2;
- }
- std::string street1;
- std::string street2;
- virtual std::string description() const
- {
- return street1 + " and " + street2;
- }
- public:
- bus_stop_corner(){}
- bus_stop_corner(const gps_position & lat_, const gps_position & long_,
- const std::string & s1_, const std::string & s2_
- ) :
- bus_stop(lat_, long_), street1(s1_), street2(s2_)
- {}
- };
5.序列化数组
- class bus_route
- {
- friend class boost::serialization::access;
- bus_stop stops[10];
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & stops;//会自动在前面加上数组的长度
- }
- public:
- bus_route(){}
- };
6.序列化stl容器
- #include <boost/serialization/list.hpp>
- class bus_route
- {
- friend class boost::serialization::access;
- std::list<bus_stop> stops;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & stops;//会自动加上容器的长度
- }
- public:
- bus_route(){}
- };
7.可根据版本号序列化
- #include <boost/serialization/list.hpp>
- #include <boost/serialization/string.hpp>
- #include <boost/serialization/version.hpp> //必须包含这个头文件
- class bus_route
- {
- friend class boost::serialization::access;
- std::list<bus_stop> stops;
- std::string driver_name;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- // only save/load driver_name for newer archives
- if(version > 0)//根据版本号序列化
- ar & driver_name;
- ar & stops;
- }
- public:
- bus_route(){}
- };
- BOOST_CLASS_VERSION(bus_route, 1) //定义version=1
8.读写分离
一直以来都是serialize这个函数做序列化很反序列化,但有时候序列化和反序列化的方法不一致,serialize函数就难以支持了,因此要用save/load函数,save做序列化操作,而load做反序列化操作。
- #include <boost/serialization/list.hpp>
- #include <boost/serialization/string.hpp>
- #include <boost/serialization/version.hpp>
- #include <boost/serialization/split_member.hpp>
- class bus_route
- {
- friend class boost::serialization::access;
- std::list<bus_stop> stops;
- std::string driver_name;
- template<class Archive>
- void save(Archive & ar, const unsigned int version) const
- {
- // note, version is always the latest when saving
- ar & driver_name;
- ar & stops;
- }
- template<class Archive>
- void load(Archive & ar, const unsigned int version)
- {
- if(version > 0)
- ar & driver_name;
- ar & stops;
- }
- BOOST_SERIALIZATION_SPLIT_MEMBER() //这个宏定义必须要在类中加上
- public:
- bus_route(){}
- };
- BOOST_CLASS_VERSION(bus_route, 1)