如何在没有类枚举器的情况下反序列化类层次结构

时间:2010-11-21 20:21:55

标签: c++ design-patterns serialization

我正在使用这种方法来序列化和反序列化类层次结构:

 // Enumeration of classes.
 struct Type {
     enum TypeEnum { A, B }
     TypeEnum t;
     Type(TypeEnum te) : t(te) { }
     bool operator == (TypeEnum te);
     void saveToStream(Stream& stream);
     void loadFromStream(Stream& stream);
 };

 // Serializable base class.
 struct A {
     Type type;
     A() { type = Type::A; }
     // ... members
     virtual void loadFromStream(Stream& stream);
     virtual void saveToStream(Stream& stream) const;
 };

 // Serializable child class.
 struct B : public A {
     B() : A() { type = Type::B; }
     virtual void loadFromStream(Stream& stream);
     virtual void saveToStream(Stream& stream);
 };

 // Helper class.
 struct Serializer {
     static A* loadFromStream(Stream& stream)
     {
        Type t;
        t.loadFromStream(stream);
        if (t == Type::A) {
           A* a = new A;
           a->loadFromStream(stream);
           return a;
        } else if (t == Type::B) {
           A* b = new B;
           b->loadFromStream(stream);
           return b;
        } 
        throw "Unknown type";
        return 0; // surpress warning
     }
     static void saveToStream(Stream& stream, const A& a)
     {
        a.type.saveToStream(stream);
        a.saveToStream(stream);
     }
 }; 

 // Usage
 B b;
 Serializer::saveToStream(stream, b);
 B* b2 = static_cast<B*>(Serializer::loadFromStream(stream));

这种方法非常简单易懂。但是我在考虑是否有一个更优雅的解决方案,而不需要在每次扩展类层次结构时更新类Type

如果没有枚举器类Type并且可能没有类Serializer,您是否有任何提示如何执行此操作?

1 个答案:

答案 0 :(得分:2)

这似乎是Factory Pattern的好候选人。

基本上,它包括委派基于给定标识符实例化正确类型的责任。对Stack Overflow的搜索提出了this answer,它提供了一个很好的C ++实现示例。请注意,工厂可以创建的所有对象都必须实现一个公共接口(这似乎是您的情况)。

实现此类模式后,您将能够删除if中的else if / Serializer::loadFromStream级联,并在工厂实例化对象上调用loadFromStream