C ++通过基类指针增强子类的序列化

时间:2018-07-04 15:21:56

标签: c++ serialization boost deserialization boost-serialization

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

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);  
...  

创建派生对象的常规方法是:

Base* obj = new Derived(anotherObj);  

反序列化是这样的:

Base* obj;
ar >> obj;  

默认的构造函数将被称为(Derived()),反序列化会继续进行,但是m_another不会反序列化,应将其传递给构造函数,所有其他字段均会反序列化。
而且,我无法在反序列化之后设置m_another,因为它实际上会影响反序列化。
我可以通过全局变量传递对anotherObj的引用-丑陋,但可以。
有什么办法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

首先,要获得该类的多态行为,您需要具有一个polymorphic type。此逻辑要求为stated in the documentation

  

事实证明,序列化的对象的类型取决于基类(在这种情况下为基类)是否是多语言的。如果base不是多态的,也就是说它没有虚函数,那么base类型的对象将被序列化。任何派生类中的信息都将丢失。如果这是所需的(通常是不需要的),则不需要其他工作。

     

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

     

[...]

执行此操作的明显方法是拥有虚拟析构函数(When to use virtual destructors?)。


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