c++ - How to perform flexible serialization of a polymorphic inheritance hierarchy? -
i have tried read advice given in c++faq on subject. have implemented system according item 36.8 , after few months (with lot of data serialized), want make changes in both public interface of of classes , inheritance structure itself.
class base { public: vector field1() const; vector field2() const; vector field3() const; std::string name() const {return "base";} }; class derived : public base { public: std::string name() const {return "derived";} };
i know how make changes such as:
split
derived
derived1
,derived2
, while mapping originalderived
derived1
existing data.split
base::field1()
base::field1a()
,base::field1b()
while mappingfield1
field1a
, havingfield1b
empty existing data.
i have
- deserialize gigabytes of old data
- convert them new inheritance structure
- reserialize them in new , more flexible way.
i know how make serialization more flexible, when decide make change in future, not facing conversion hell now.
i thought of making system use numbers instead of names serialize objects. example base = 1, derived1 = 2, ... , separate number-to-name system convert numbers names, when want change name of class, in separate number-to-name system, without changing data.
the problems approach are:
the system brittle. changing in number-to-name system possibly change meaning of gigabytes of data.
the serialized data lose of human readability, since in serialized data, there numbers instead of names.
i sorry putting many issues 1 question, inexperienced @ programming , problem facing seems overwhelming not know start.
any general materials, tutorials, idioms or literature on flexible serialization welcomed!
it's bit late now, whenever designing serialization format, should provide versionning. can mangled type information in stream, or treated separate (integer) field. when writing class out, write latest version. when reading, have read both type , version before can construct; if you're using static map suggested in faq, key be:
struct deserializekey { std::string type; int version; };
given situation in now, solution mangle version type name in recognizable way, along lines of type_name__version
; if type_name
isn't followed 2 underscore, use 0. isn't efficient method, it's acceptable, , solve problem backwards compatibility, while providing evolution in future.
for precise questions:
in case,
derived
previous version ofderived1
. can insert necessary factory function map under appropriate key.this classical versionning. version 0 of
base
hasfield1
attribute, , when deserialize, use initializefield1a
, , initializefield1b
empty. version 2 ofbase
has both.
if mangle version type name, suggest above, shouldn't have convert existing data. long term, of course, either of older versions disappear data sets, can remove support them, or program keeps getting bigger, support lots of older versions. in practice, i've seen latter.
Comments
Post a Comment