C++序列化库的实现

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;
}

接下来是完整库截图

C++序列化库的实现


// 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  }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/4027141282656c44471a7b6eeb1dc451.html