简体   繁体   中英

C++ boost serialization of subclass by base class pointer

I perform serialization / deserialization of a subclass object by a pointer to its base class. Everything works Ok, yet I miss one feature: adding a runtime parameter to the constructor of the object being deserialized, example:

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

My normal way to create a Derived object is:

Base* obj = new Derived(anotherObj);  

The deserialization goes like this:

Base* obj;
ar >> obj;  

The default constructor will be called (Derived()), and deserialization proceeds, BUT m_another is not deserialized, it should be passed to the constructor, all the other fields are deserialized.
Moreover, I cannot set m_another after the deserialization, because it actually influences the deserialization.
I can pass reference to anotherObj via a global variable - ugly, but works.
Is there any way to solve it in a not so ugly manner ?

First off, to get polymorphic behaviour of the class you need have a polymorphic type . This logical requirement is stated in the documentation :

It turns out that the kind of object serialized depends upon whether the base class (base in this case) is polymophic or not. If base is not polymorphic, that is if it has no virtual functions, then an object of the type base will be serialized. Information in any derived classes will be lost. If this is what is desired (it usually isn't) then no other effort is required.

If the base class is polymorphic , an object of the most derived type (derived_one or derived_two in this case) will be serialized. The question of which type of object is to be serialized is (almost) automatically handled by the library.

[...]

The obvious way to enforce this is to have the virtual destructor ( When to use virtual destructors? ).


Next up, to (de)serialize types using a non-default constructor, use save_construct_data / load_construct_data . Again, the docs are a good start.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM