C++中经常需要用到序列化与反序列化功能,由于C++标准中没有提供此功能,于是就出现了各式各样的序列化库,如boost中的,如谷歌的开源项目,但是很多库都依赖其他库过于严重,导致库变得很庞大.今天来分享一个我写的序列化库,在写库的时候,我有一个使用上是否方便的标准,那就是别人用了你的库,需要写多少行代码.下面将要提供的这个库理论上是夸平台的,因为用的都是C++标准语法.这个库性能,以前写的时候就拿来跟boost中的还是谷歌的开源项目相比较过(具体是哪个,时间久忘了是),结果我记得很清楚,速度上慢了一倍.后来发现是实现上多了一次拷贝,所以还是有提升空间的.
这个库使用上相当方便,只需要使用三种操作符即可: << , >> , & , 同时需要用到traits库,想要获取traits请看上一篇博文.
这个库提供两类archive,一种是string(wstring也可以),一种是fstream,本来还想提供xml格式的和二进制格式的,但是由于后来工作忙就没有继续提供,序列化的对象包括基本类型,用户自定义类型,stl库里常用的容器,不支持的容器各位可以拿来扩展一下,到时候别忘了分享给我哈.
废话不说,上代码,老规矩,先写用例,接下来再贴完整的库,把各个hpp文件拷贝下来即可使用(这里不支持上传文件,贴库好辛苦,要体谅):
#include<iostream>
#include "../../traits/traits.hpp"
#include "../../serialization/archive.hpp"
using namespace std;
struct Student
{
int _idx;
float _weigth;
std::string _name;
std::list<std::string> _familyName_list;
// 要定义成public的
template<typename Arch>
void serialize(Arch& arch, unsigned int ver)
{
// ver是版本号
arch & _idx
& _weigth
& _name
& _familyName_list;
}
};
int main()
{
Student stu; // 有一个学生
stu._idx = 1; // 编号1
stu._weigth = 120.45f;// 重120多斤 浮点精度可通过宏SERIALIZATION_FLOAT_PRECISION控制
stu._name = "小明";//名字叫小明
stu._familyName_list.push_back("爸爸");
stu._familyName_list.push_back("妈妈");
stu._familyName_list.push_back("姐姐");
// 定义一个archive类型
std::string ostr;
// 定义一个序列化对象,它的原型是typedef serialization::string_iarchive<std::string> default_string_iarchive;
serialization::default_string_oarchive oarch(ostr); //
// 奇迹来了
oarch & stu; // 或者写oarch<<stu;
cout << ostr << endl;
// 反序列化
Student stu2;
serialization::default_string_iarchive iarch(ostr);
iarch & stu2; // 或者写iarch>>stu2; 调试模式下观看stu2的值
// 关于指针的序列化
std::string ostr2;
serialization::default_string_oarchive oarch2(ostr2); //
// 这个序化出来的是地址,并非值,之所以有这样的设定,是因为serialization序列化的是变量的值,并不是变量指
// 向的值,如果不这样设定,那在反序列化的时候会遇到内存分配的尴尬
// 读者亲自试验一下便懂得这个道理
char* pchar = "fdsfdsfsf";
oarch2 & pchar;
return 0;
}
接下来是完整库截图
// archive.hpp
#ifndef ARCHIVE_INCLUDE
#define ARCHIVE_INCLUDE
#include "string_archive.hpp"
#include "wstring_archive.hpp"
#include "stream_archive.hpp"
#include "wstream_archive.hpp"
#include "xml_archive.hpp"
#include <string>
#include <fstream>
#ifdef USE_XML_ARCHIVE
#include "tinyxml/tinyxml.h"
#endif
NAMESPACE_SERIALIZATION_BEGIN
typedef serialization::string_iarchive<std::string> default_string_iarchive;
typedef serialization::string_oarchive<std::string> default_string_oarchive;
typedef serialization::wstring_iarchive<std::wstring> default_wstring_iarchive;
typedef serialization::wstring_oarchive<std::wstring> default_wstring_oarchive;
typedef serialization::stream_iarchive<std::ifstream> file_stream_iarchive;
typedef serialization::stream_oarchive<std::ofstream> file_stream_oarchive;
typedef serialization::wstream_iarchive<std::wifstream> file_wstream_iarchive;
typedef serialization::wstream_oarchive<std::wofstream> file_wstream_oarchive;
NAMESPACE_SERIALIZATION_END
#endif
// archive_config.hpp
#ifndef ARCHIVE_CONFIG_INCLUDE
#define ARCHIVE_CONFIG_INCLUDE
#define NAMESPACE_SERIALIZATION_BEGIN namespace serialization{
#define NAMESPACE_SERIALIZATION_END }