c++ - Serializing polymorphic classes with environment-specific state -


i have classes this:

class base { public:     virtual ~base() {}     ... };  class derived1 {     outerstate1& outerstate;     innerstate1 innerstate;     ...     template <typename ar>     void serialize(ar& ar, const unsigned int /*version*/) {         ar & innerstate;     } public:     derived1(outerstate1& outerstate) : outerstate(outerstate) {}     ... };  class derived2 {     outerstate2& outerstate;     innerstate2 innerstate;     ...     template <typename ar>     void serialize(ar& ar, const unsigned int /*version*/) {         ar & innerstate;     } public:     derived1(outerstate2& outerstate) : outerstate(outerstate) {}     ... }; 

basically, classes have state depends on outside environment, , don't want serialize it. state may different different subclasses. want serialize class. thing boost::serialization handles polymorphic classes well, seems me not enough me. find following ways serialize these objects, neither like:

  1. use global variables outer state. either use these global variables inside class, or overload load_construct_data() , create objects global variable. problem solution requires global variables, bad design, , breaks if program needs handle more 1 such states.

  2. do not use polymorphic serialization feature of boost. instead, save actual type in enum, save object non-polymorphically. when loading, load type enum, in switch create object of appropriate type appropriate outer state, load object non-polymorphically. problem have lot of manual coding automagically done boost, , doesn't work if want serialize collection of such objects.

is there better, more elegant solution problem?

the solution save environment-specific state pointer in class. save/load in archive before actual classes, , modify value. serialization of base class looks this:

class derived1 {     outerstate1& outerstate;     innerstate1 innerstate;     ...     template <typename ar>     void serialize(ar& ar, const unsigned int /*version*/) {         ar & innerstate;     } public:     derived1(outerstate1& outerstate) : outerstate(outerstate) {}     const outerstate1& getouterstate() const { return outerstate; }     ... };      template <typename ar>     void save_construct_data(ar& ar, const derived1* object, const unsigned int /*version*/) {         ar << &object.getouterstate();     }      template <typename ar>     void load_construct_data(ar& ar, derived1* object, const unsigned int /*version*/) {         outerstate1* state;         ar >> state;         ::new(object)derived1{*state};     } 

make serialization of environment specific object nop.

template <typename ar> void serialize(ar&, outerstate1&, const unsigned int) { } 

when saving, this:

outerstate1 outerstate1; outerstate2 outerstate2; std::shared_ptr<base> object = getobject(); ... // saving starts archive << outerstate1 << outerstate2 << object; ... 

when loading, load states, override them. suppose outerstate1 , outerstate2 located @ same position before, , has new, desired value.

std::shared_ptr<base> object; archive >> outerstate1 >> outerstate2 >> object; 

on note, code presented in question not complete. base class serialization needs done, that's beside point now.


Comments

Popular posts from this blog

twig - Using Twigbridge in a Laravel 5.1 Package -

firemonkey - How do I make a beep sound in Android using Delphi and the API? -

jdbc - Not able to establish database connection in eclipse -