首页 > 解决方案 > C++通过基类指针提升子类的序列化

问题描述

我通过指向其基类的指针执行子类对象的序列化/反序列化。一切正常,但我错过了一个功能:向要反序列化的对象的构造函数添加运行时参数,例如:

class Base {  
public:  
    Base(AnotherClass* another)  
        :m_another(another)  
    {}  
protected:  
    AnotherClass* m_another;  
};  
class Derived : public Base {  
public:  
    Derived(AnotherClass* another)  
        :Base(another)  
    {}  
    Derived()  
        :Base(nullptr)  
    {}  
private:  
    /* different other members */  
};  
BOOST_CLASS_EXPORT(Derived);  
...  

我创建 Derived 对象的常规方法是:

Base* obj = new Derived(anotherObj);  

反序列化是这样的:

Base* obj;
ar >> obj;  

默认构造函数将被调用(Derived()),并进行反序列化,但是 m_another 没有反序列化,它应该传递给构造函数,所有其他字段都被反序列化。
此外,我不能在反序列化后设置 m_another,因为它实际上会影响反序列化。
我可以通过全局变量传递对 anotherObj 的引用 - 丑陋,但有效。
有没有办法以不那么丑陋的方式解决它?

标签: c++serializationboostdeserializationboost-serialization

解决方案


首先,要获得类的多态行为,您需要一个多态类型文档中说明了此逻辑要求:

事实证明,序列化的对象类型取决于基类(在本例中为基类)是否是多态的。如果 base 不是多态的,即没有虚函数,那么 base 类型的对象将被序列化。任何派生类中的信息都将丢失。如果这是所需要的(通常不是),则不需要其他努力。

如果基类是多态的,那么最派生类型的对象(在这种情况下是derived_one 或derived_two)将被序列化。要序列化哪种类型的对象的问题(几乎)由库自动处理。

[...]

执行此操作的明显方法是使用虚拟析构函数(何时使用虚拟析构函数?)。


接下来,要使用非默认构造函数(反)序列化类型,请使用save_construct_data/ load_construct_data。同样,文档是一个好的开始。


推荐阅读