[WIP]C++ cereal对象序列化库使用总结
近段有对C++对象序列化的需求,因此了解了一下C++的序列化库,网上搜到的主要是protocolbuf和boost::serialization这两个。而这两者均不太满足自己的需求,protocolbuf是需要按照其规则定义好对象的结构,之后生成相应的序列化和反序列化代码,而自己需要对现有的部分C++代码中的对象进行序列化,如果要使用protocolbuf,成本太高。boolst::serialization库实际上是满足需求的,只是它的代码太多了,不想因为这个简单的需求带上那么多的代码。
介绍
cereal是一个只有头文件的C++序列化库,它能够将任何数据类型转换为二进制编码或是xml文件或是json文件,也可以将转换后的文件恢复成原来的数据结构。cereal被设计为快速、轻量和易于扩展的,同时其不依赖任何其他第三方库,因此可以非常容易被已有的工程所使用。
概括来说,其主要有这些特点:
- cereal 为标准库中的几乎所有类型都提供了开箱即用的序列化支持,支持多态和继承。但是不支持原始指针和引用,但智能指针(如
std::shared_ptr和std::unique_ptr)则没有问题。 - cereal的性能很高,它通常比boost的serialization库更快,同时产生的二进制文件却更小。
- cereal支持将C++对象序列化为二进制、xml、json文件,如果希望支持其他的文件类型,cereal的代码结构也可以很容易的让你进行扩展。
- cereal非常易于使用,它完全由头文件实现,不依赖第三方库,文档很完善。同时增加了很多静态检查,以便于将错误提前暴露至编译期。
- cereal的代码经过了单元测试的检验,质量可靠。
- BSD协议,协议友好。
序列化arhcive文件
3种archive分别对应3个头文件:
#include <cereal/archives/binary.hpp>#include <cereal/archives/json.hpp>#include <cereal/archives/xml.hpp>
每种archive都会实现2个RAII类,以二进制格式为例:
cereal::BinaryInputArchive:用于读取序列化archive文件,需要接受一个std::istream对象为参数。重载了operator()/operator<<用于实现反序列化cereal::BinaryOutputArchive:用于写入序列化archive文件,需要接受一个std::ostream对象为参数。重载了operator()/operator<<用于实现序列化
注意:JSON和XML的RAII类只有在其被销毁是才能安全地完成内存数据到磁盘文件的刷新!(可以看其实现)
序列化函数
cereal的序列化和反序列化基于3类trait函数,在编译时会自动选择:
- 单一的序列化函数:
serialize():序列化和反序列化
- 成对的序列化函数:
save()/load():序列化/反序列化save_minimal()/load_minimal():序列化/反序列化(用的很少,毕竟要压缩大小时不如直接lz4压缩再解压)
一般来说建议用单独的 serialize() 方法更简单,但如果需要在类的构造函数/析构函数前后进行额外的操作(比如需要传入一块外部分配的内存指针),则可以用成对的 save()/load() 函数。

注意:
-
3种序列化函数只能出现其中1种
-
save()函数必须是常成员函数或者是接收const 被序列化的类&的非成员函数。 -
如果选择类外实现序列化函数,则必须置于与其序列化的类型相同的命名空间中,或者
cereal命名空间中 -
对标准库容器进行序列化之前一定要包含cereal对应的头文件(在cereal头文件的types目录下),否则会编译失败,提示
cereal could not find any output serialization functions for the provided

最低0.47元/天 解锁文章
1425

被折叠的 条评论
为什么被折叠?



