2

有没有办法在 C++ 中序列化一个类?我指的不是类的实例,而是类本身。反序列化时,我不知道要实例化哪个类来调用反序列化。我希望能够以某种方式确定所代表的类,实例化它的一个空实例,然后调用反序列化它。

编辑澄清:

我正在创建一个键值结构,其中每个键都有一个强类型值。(一些键必须存储字符串,其他键必须存储整数,还有一些键可能存储任意值)。我设计了一个系统,由编译器通过模板强制执行。

Key 类有两个模板参数:

  • UniqueClass - 每个概念应该有一个唯一的类(通常在定义概念的预处理器函数中定义)
  • ValueType - 这是该概念的值必须是的类

Value 类是一个模板类,只有 ValueType 有一个抽象超类,因此我可以在其中包装任何类(类似于 boost::any)。

然后在我的键值结构中,我存储和检索使用 ConceptType 和 ValueType 模板化的函数:

template<UniqueClass, ValueType>
void store( Concept<UniqueClass, ValueType> concept, ValueType value );

因为我使用相同的模板来描述概念的值类型和传入的值,所以如果它们不匹配,编译器会报错。

我现在希望能够序列化键值存储。因此,我需要以某种方式序列化模板化的 Concept 类,然后在反序列化期间实例化正确的任意类。

我有它,以便我可以调用序列化并要求所有适当的对象序列化自己,我只是不知道在反序列化期间要实例化哪个类以要求反序列化自身。

4

1 回答 1

3

由于问题编辑而更新了答案:

我的理解是,在您手动或通过反序列化添加之前,您在容器中有 0 个密钥。有两种方法可以做到这一点:侵入式和非侵入式。

侵入式

Concept<U,T>继承自Deserializable

class Deserializable
{
    public:
        virtual void deserialize(InputStream& s) = 0;
        virtual int getClassId() const = 0;
};

现在,您可以通过它的 id 来识别一个类,使用getClassId(). 所以,接下来就是创建一个工厂。在这里,我将使用一个非常简单的方法,用std::map, 来说明这一点;随意使用更复杂的。

typedef Deserializable* (*createDeserializableType)();
std::map<int,createDeserializableType> factory;

// ...

factory[id1] = &createMyClass;
// etc...

// ...

// On deserialization
createDeserializable create = factory[idReadFromStream];
if(create)
    create()->deserialize(input_stream);

这意味着要么你必须添加一个store方法,Deserializable要么你添加一个store方法Deserializable(我个人更喜欢最后一种方法)。

非侵入式

这个想法是在创建和添加键值的同时反序列化它:

typedef void (*deserializeFctType)(InputStream&);
typedef int id_type;
std::map<id_type,deserializeFctType> factory;

deserialize方法将在创建后立即存储反序列化类型。

您的问题中不清楚的是接受列表的列表是有限的还是无限的。只有有限的类型集是“容易”序列化的。

于 2012-10-04T20:25:27.410 回答