关于序列化:是否可以在C ++中序列化和反序列化一个类?

Is it possible to serialize and deserialize a class in C++?

是否可以在C ++中序列化和反序列化一个类?

我已经使用Java 3年了,序列化/反序列化在这种语言中相当简单。 C ++有类似的功能吗? 是否有处理序列化的本机库?

一个例子会有所帮助。


Boost::serialization库相当优雅地处理它。我在几个项目中使用过它。这里有一个示例程序,展示如何使用它。

唯一的本地方法是使用流。这基本上都是Boost::serialization库所做的,它通过设置框架来扩展stream方法,将对象写入类似文本的格式并从相同的格式读取它们。

对于内置类型,或正确定义operator<<operator>>的您自己的类型,这非常简单;有关更多信息,请参阅C ++ FAQ。


我意识到这是一个老帖子,但它是搜索c++ serialization时出现的第一个帖子。

我鼓励任何有权使用C ++ 11的人来看看Grain,这是一个C ++ 11头文件库,用于序列化,支持开箱即用的二进制,JSON和XML。谷物的设计易于扩展和使用,并具有与Boost类似的语法。


提升是一个很好的建议。但如果你想自己动手,那就不那么难了。

基本上,您只需要一种方法来构建对象图,然后将它们输出为某种结构化存储格式(JSON,XML,YAML等等)。构建图形就像利用标记递归体面对象算法然后输出所有标记对象一样简单。

我写了一篇文章描述了一个基本的(但仍然很强大的)序列化系统。您可能会觉得有趣:使用SQLite作为磁盘文件格式,第2部分。


Boost :: serialization是一个很好的选择,但是我遇到了一个新项目:我发现它更优雅的谷歌!我强烈建议调查它。


我推荐Google协议缓冲区。
我有机会在一个新项目上测试驱动库,它非常容易使用。
该库针对性能进行了大量优化。

Protobuf与其他序列化解决方案的不同之处在于它不会对您的对象进行序列化,而是根据您的规范为序列化的对象生成代码。


就"内置"库而言,<<>>已专门用于序列化。

您应该覆盖<<以将对象输出到某个序列化上下文(通常是iostream)和>>以从该上下文中读取数据。每个对象负责输出其聚合的子对象。

只要对象图不包含循环,此方法就可以正常工作。

如果是,那么您将不得不使用库来处理这些周期。


您可以检查amef协议,amef中的C ++编码示例如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    //Create a new AMEF object
    AMEFObject *object = new AMEFObject();

    //Add a child string object
    object->addPacket("This is the Automated Message Exchange Format Object property!!","adasd");  

    //Add a child integer object
    object->addPacket(21213);

    //Add a child boolean object
    object->addPacket(true);

    AMEFObject *object2 = new AMEFObject();
    string j ="This is the property of a nested Automated Message Exchange Format Object";
    object2->addPacket(j);
    object2->addPacket(134123);
    object2->addPacket(false);

    //Add a child character object
    object2->addPacket('d');

    //Add a child AMEF Object
    object->addPacket(object2);

    //Encode the AMEF obejct
    string str = new AMEFEncoder()->encode(object,false);

在java中解码就像,

1
2
3
    string arr = amef encoded byte array value;
    AMEFDecoder decoder = new AMEFDecoder()
    AMEFObject object1 = AMEFDecoder.decode(arr,true);

协议实现具有C ++和Java的编解码器,有趣的是它可以以名称值对的形式保留对象类表示,
我在上一个项目中需要一个类似的协议,当我偶然发现这个协议时,我实际上根据我的要求修改了基本库。希望这对你有所帮助。


Sweet Persist是另一个。

可以使用XML,JSON,Lua和二进制格式对流进行序列化。


我推荐使用其他海报所描述的boost序列化。这是一个很好的详细教程,介绍如何使用它,很好地补充了增强教程:http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-serialization/


我建议调查抽象工厂,这些工厂经常被用作序列化的基础

我在另一个关于C ++工厂的问题中回答过。如果有兴趣,请查看灵活的工厂。我试着用ET ++来描述一种旧的方法来使用对我来说很有用的宏。

ET ++是一个将旧MacApp移植到C ++和X11的项目。为此,Eric Gamma等开始考虑设计模式。 ET ++包含在运行时进行序列化和内省的自动方法。


如果你想要简单和最好的性能并且不关心向后数据兼容性,那么试试HPS,它的重量轻,比Boost快得多,并且比Protobuf等更容易使用。

例:

1
2
3
std::vector<int> data({22, 333, -4444});
std::string serialized = hps::serialize_to_string(data);
auto parsed = hps::parse_from_string<std::vector<int>>(serialized);