内容简介:使用Boost做对象序列化是非常方便的,本文将介绍一种序列化STL标准容器的方法。这是之前设计的异步框架的一个子功能:过程A将标准容器数据序列化成二进制流,然后将该二进制数据发送到过程B,过程B将数据反序列化为标准容器。下面这个基类支持vector、set、unordered set、multiset、unordered multiset、map、unordered map、multimap和unordered multimap。
使用Boost做对象序列化是非常方便的,本文将介绍一种序列化STL标准容器的方法。
这是之前设计的异步框架的一个子功能:过程A将标准容器数据序列化成二进制流,然后将该二进制数据发送到过程B,过程B将数据反序列化为标准容器。 (转载请指明出于breaksoftware的csdn博客)
下面这个基类支持vector、set、unordered set、multiset、unordered multiset、map、unordered map、multimap和unordered multimap。
/************************************************************************* > File Name: serialization.h > Author: fangliang > Mail: fangliang1988@gmail.com > Created Time: Fri 23 Mar 2018 03:11:14 PM CST ************************************************************************/ #ifndef STLSERIALIZATION_SERIALIZATION_H #define STLSERIALIZATION_SERIALIZATION_H #include <string> #include <sstream> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> namespace stl_serialization { template<class T> class Serialization : public T { public: void serialization(std::ostringstream& ostream) { boost::archive::binary_oarchive oa(ostream); oa << *this; } void unserialization(std::istringstream& istream) { boost::archive::binary_iarchive ia(istream); ia >> *this; } private: friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int version) { ar & boost::serialization::base_object<T>(*this); } }; } #endif // STLSERIALIZATION_SERIALIZATION_H
可被序列化的标准容器只要继承该基类即可。以map为例
/************************************************************************* > File Name: map_serialization.h > Author: fangliang > Mail: fangliang1988@gmail.com > Created Time: Thu 22 Mar 2018 11:09:11 PM CST ************************************************************************/ #ifndef STLSERIALIZATION_MAP_SERIALIZATION_H #define STLSERIALIZATION_MAP_SERIALIZATION_H #include <map> #include <string> #include <sstream> #include <boost/serialization/map.hpp> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> #include "serialization.h" namespace stl_serialization { template<class T, class T1> class MapSerialization : public Serialization<std::map<T, T1> > { }; } #endif // STLSERIALIZATION_MAP_SERIALIZATION_H
使用一个单元测试来测试这段代码
/************************************************************************* > File Name: ut_map_serialization.cpp > Author: fangliang > Mail: fangliang1988@gmail.com > Created Time: Thu 22 Mar 2018 11:11:46 PM CST ************************************************************************/ #include "gtest/gtest.h" #include "./src/stl_serialization/map_serialization.h" using stl_serialization::MapSerialization; int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } namespace unit_test { class UtMapSerialization : public ::testing::Test { protected: virtual void SetUp() { MapSerialization<int, std::string> ms_src; for (int i = 0; i < _size; i++) { ms_src[i] = " "; } ms_src.serialization(_ost); } virtual void TearDown() {} protected: int _size = 10000; std::ostringstream _ost; }; TEST_F(UtMapSerialization, SizeEq) { MapSerialization<int, std::string> ms_des; std::istringstream ist(_ost.str()); ms_des.unserialization(ist); ASSERT_EQ(_size, ms_des.size()); } TEST_F(UtMapSerialization, ElemEq) { MapSerialization<int, std::string> ms_des; std::istringstream ist(_ost.str()); ms_des.unserialization(ist); int i = 0; for (std::map<int, std::string>::iterator it = ms_des.begin(); it != ms_des.end(); it++) { ASSERT_EQ(it->first, i++); } } }
如果STL的容器中存放在的是一个非标准类型,比如一个用户自定义类型,则需要让该类型实现serialize方法。以vector为例
/************************************************************************* > File Name: vector_serialization.h > Author: fangliang > Mail: fangliang1988@gmail.com > Created Time: Thu 22 Mar 2018 03:41:16 PM CST ************************************************************************/ #ifndef STLSERIALIZATION_VECTOR_SERIALIZATION_H #define STLSERIALIZATION_VECTOR_SERIALIZATION_H #include <vector> #include <string> #include <sstream> #include <boost/serialization/vector.hpp> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> #include "serialization.h" namespace stl_serialization { template<class T> class VectorSerialization : public Serialization<std::vector<T> > { }; } #endif // STLSERIALIZATION_VECTOR_SERIALIZATION_H
下面代码中,由于TestData是容器承载的类型,所以它需要增加24~33行代码用于容器内对象序列化。
/************************************************************************* > File Name: ut_vecotr_serialization.cpp > Author: fangliang > Mail: fangliang1988@gmail.com > Created Time: Wed 21 Mar 2018 02:34:18 PM CST ************************************************************************/ #include "gtest/gtest.h" #include "./src/stl_serialization/vector_serialization.h" using stl_serialization::VectorSerialization; int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } namespace unit_test { struct TestData { int interger; double db; float fl; std::string str; private: friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int version) { ar & interger; ar & db; ar & fl; ar & str; } }; class UtVectorSerialization : public ::testing::Test { protected: virtual void SetUp() { VectorSerialization<int> vs_src; for (int i = 0; i < _size; i++) { TestData item; item.interger = i; item.db = i; item.fl = i; item.str = std::to_string(i); vs_src.push_back(item); } vs_src.serialization(_ost); } virtual void TearDown() {} protected: int _size = 10000; std::ostringstream _ost; }; TEST_F(UtVectorSerialization, SizeEq) { VectorSerialization<int> vs_des; std::istringstream ist(_ost.str()); vs_des.unserialization(ist); ASSERT_EQ(_size, vs_des.size()); } TEST_F(UtVectorSerialization, ElemEq) { VectorSerialization<int> vs_des; std::istringstream ist(_ost.str()); vs_des.unserialization(ist); for (int i = 0; i < _size; i++) { const TestData& item = vs_des.at(i); ASSERT_EQ(item.interger, i); ASSERT_DOUBLE_EQ(item.db, i); ASSERT_FLOAT_EQ(item.db, i); std::string str = std::to_string(i); ASSERT_STREQ(item.str.c_str(), str.c_str()); } } }
最后我们看下包含10000个对象的容器反序列化耗时,总体来说效率还是不错的。
最后说下,unordered set、unordered multiset、unordered map和unordered multimap等不保证序列化前后容器中元素顺序一致。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
在线进制转换器
各进制数互转换器
html转js在线工具
html转js在线工具