【问题标题】:How to deserialize a class hierarchy without a class enumerator如何在没有类枚举器的情况下反序列化类层次结构
【发布时间】:2011-05-13 12:18:32
【问题描述】:

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

 // 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,您是否有任何提示?

【问题讨论】:

  • 嗯,是的,有可能。您可以同时进行静态和动态注册,但实现实际上取决于您想要放置它的位置。它可以驻留在构建系统中,可以使用宏/模板元程序生成,甚至可以是动态的。

标签: c++ design-patterns serialization


【解决方案1】:

这似乎是Factory Pattern 的好候选。

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

一旦你实现了这种模式,你就可以删除Serializer::loadFromStream中的if/else if级联,只需在工厂实例化对象上调用loadFromStream

【讨论】:

  • 顺便说一下,这是QUiLoader 使用的方法(当然,它会序列化为XML)。
  • 查看提供的示例,我相信if/else if 级联是一种更直接且更易于理解的方法。
猜你喜欢
  • 2019-05-31
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
相关资源
最近更新 更多