我试图仔细阅读C++FAQ中有关此主题的所有建议。我已根据项目36.8 实现了我的系统,现在几个月后(有大量数据序列化),我想在某些类的公共接口和继承结构本身进行更改。
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";}
};
我想知道如何进行更改,例如:
将Derived
拆分为Derived1
和Derived2
,同时将原始Derived
映射到Derived1
以获取现有数据。
将Base::field1()
分割为Base::field1a()
和Base::field1b()
,同时将field1
映射到field1a
,并为现有数据设置field1b
为空。< / p>
我必须
我想知道如何使序列化更加灵活,这样当我决定将来做出一些改变时,我就不会像现在这样面对转换地狱。
我想过制作一个使用数字代替名字的系统来序列化我的对象。例如,Base = 1,Derived1 = 2,...以及一个单独的数字到名称系统,将数字转换为名称,这样当我想要要更改某个类的名称,我只会在这个单独的number-to-name系统中进行,而不会更改数据。
这种方法的问题是:
系统脆弱。这就是改变数字到系统系统中的任何内容都可能会改变千兆字节数据的含义。
序列化数据会失去一些人类可读性,因为在序列化数据中,会有数字而不是名称。
我很抱歉把这么多问题放在一个问题上,但我对编程缺乏经验,而我面临的问题似乎太过于无法解决,我只是不知道从哪里开始。
关于灵活序列化的任何一般材料,教程,习语或文献都是最受欢迎的!
答案 0 :(得分:2)
现在可能有点晚了,但每当设计时 序列化格式,您应该提供版本控制。 这可能会被损坏到流中的类型信息中,或者 作为单独的(整数)字段处理。写课时 出来,你总是写最新版本。在阅读时,你 你必须先阅读类型和版本 构造;如果您使用常见问题解答中建议的静态地图, 那么关键是:
struct DeserializeKey
{
std::string type;
int version;
};
鉴于你现在的情况,解决方案可能是
将版本变成类型名称,清晰可辨
方式,说出一些东西
type_name__version
;如果
type_name
后跟两个下划线,
然后使用0.这不是最有效的方法,但它是
通常可以接受,并将向后解决问题
兼容性,同时在未来提供进化。
准确问题:
在这种情况下,Derived
只是以前的版本
Derived1
。您可以插入必要的工厂功能
适当的密钥下的地图。
这只是经典版本。 Base
的版本0有
一个field1
属性,当您反序列化时,您可以使用它
初始化field1a
,并将field1b
初始化为空。
Base
的第2版同时包含。
如果您将版本修改为类型名称,我建议 以上,您不必转换任何现有数据。长 当然,这个术语只是一些旧版本 从您的数据集中消失,以便您可以删除 对他们的支持,或者你的程序越来越大 支持许多旧版本。在实践中,我通常都是 见过后者。
答案 1 :(得分:0)
也许Thrift可以帮助你做到这一点。