【问题标题】:Boost Serialization: pointer conainer to <BASE> contains various of DERIVED objectsBoost 序列化:指向 <BASE> 的指针容器包含各种 DERIVED 对象
【发布时间】:2014-01-07 09:37:16
【问题描述】:

我有一个带有序列化方法的类型类节点。 Node 有派生类:BigNide、SmallNode..(等等)。以及它们的派生类——VitalBigNode。 它们中的每一个也都有序列化方法,该方法调用了他的基类的序列化方法。 (通过序列化::base_object)。 到目前为止,serialize 非常适合各种节点。

这是棘手的部分: 有一个 (Node*)s(指向节点的指针)的列表容器,其中包含来自各种节点(派生类)的对象。 我想序列化这个容器。我已经拼命尝试了许多 unique_ptr、shared_ptr、多态、BOOST_CLASS_EXPORT 等的组合使用,但都是徒劳的。

列表“序列化器”将列表中的每个对象都关联为纯 Node 对象。它调用 Node 类的 serialize 方法。当然,它会抛出一个错误——一个丑陋的错误。

仍在尝试解决问题,在Node类的序列化方法中,我尝试编写代码来识别派生类并在序列化之前将对象动态转换为派生转换。由于必须在其派生类之前声明 Node,这是非常有问题的。此外,必须在 Node 声明头中设置 serialize 方法的 DEFINITION。所以我不能只在 Node 声明中声明 Node::serialize,然后包含派生类,然后定义 Node::serialize 方法。

一定有我错过的充分且已知的解决方案!

非常感谢您的帮助! 埃拉德。

【问题讨论】:

    标签: c++ pointers serialization boost polymorphism


    【解决方案1】:

    这是 Boost.Serialization 的一个经典(且可解决的)问题。我敢打赌,您可以在 SO 上找到它多次回答。总结如下:

    A.一种方法:在创建存档之后但在反序列化存档之前,教存档关于期望哪些派生类:

     ar.template register_type<BigNode>();
     ar.template register_type<Node>();
    

    等等。 (为了保存这些调用是自动完成的)。通常我将这些调用放入某个函数中,然后放入某个单独的文件中。

    B.替代方法:创建一个单独的 cpp 文件并将宏放在那里

     BOOST_CLASS_EXPORT(BigNode);
     BOOST_CLASS_EXPORT(Node);
    

    将它们放在一起非常重要,因为每个宏都会对某个静态对象进行评估,并且这些对象的初始化顺序是健壮的,这一点很重要;只有当所有宏都在同一个编译单元中时,才能保证这种健壮性。

    当然,始终使用“ar & p”之类的序列化代码,而不是“ar

    【讨论】:

    • 有效!非常感谢您的快速答复!
    • 我正在编写一个 CGI 库。如果一个人想使用该库并制作自己的“Node”类,他可以写“BOOST_CLASS_EXPORT(MyNewNode);”吗?在他的项目中?
    • 添加 MyNewNode 类后创建的档案应该可以正常工作。根据我的经验,它可能不适用于较旧的档案 - 除非您使用上述方法之一(即使在那里,在较旧的宏之后添加 BOOST_CLASS_EXPORT(MyNewNode) 会更安全)。原因如下:宏 BOOST_CLASS_EXPORT 初始化一个局部静态变量,通过将类信息放入某个容器中来生成某个类 ID。如果您希望这些 ID 向后兼容,您希望避免“静态对象初始化顺序”的不确定性。
    猜你喜欢
    • 2013-07-12
    • 1970-01-01
    • 2013-03-31
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多