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:
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.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
Post a Comment