C++ 存储一个类';s在文件中键入

C++ 存储一个类';s在文件中键入,c++,C++,我有一个classNodeManager。它基本上保存了一个节点*及其相互连接的列表。实际上,它管理的节点是从节点类派生的类。 现在,我希望这个NodeManager能够保存并将其所有节点归档并加载回来 我面临的问题是如何存储节点的派生类型 我在考虑存储派生类的typeid,并保留节点可以派生到的可能类型的列表,但我不知道如何实现这一点 性能不是问题,在我们讨论的任何情况下,在基类中,创建返回某种“ID”的抽象虚拟方法。(字符串、int、enum等) 在“save”方法中,首先为所有类写入ID。

我有一个class
NodeManager
。它基本上保存了一个
节点*
及其相互连接的列表。实际上,它管理的节点是从
节点
类派生的类。 现在,我希望这个
NodeManager
能够保存并将其所有节点归档并加载回来

我面临的问题是如何存储节点的派生类型

我在考虑存储派生类的
typeid
,并保留
节点可以派生到的可能类型的列表,但我不知道如何实现这一点


性能不是问题,在我们讨论的任何情况下,在基类中,创建返回某种“ID”的抽象虚拟方法。(字符串、int、enum等)

在“save”方法中,首先为所有类写入ID。您可以将ID写入嵌入基类,这样派生类就不会重写此行为

typedef SomeType ClassId;

class Serializeable{
protected:
   virtual ClassId getClassId() const = 0;
   virtual void saveData(OutStream &out) = 0;
public:
   void save(OutStream &out){
       out << getClassId();
       saveData(out);
   }
};
typedef SomeType ClassId;
类可序列化{
受保护的:
虚拟ClassId getClassId()常量=0;
虚拟void saveData(流出和流出)=0;
公众:
无效保存(扩展和输出){

如前所述,为每个类型添加一个属性,然后添加一个重载的“read()这是一个想法,但是管理者如何知道,分配和读取哪个类?我的意思是存储什么属性,以及如何准确地避免更改
NodeManager
以了解关于@yngum的新类型显示我在boost::seria中没有看到任何东西它帮助我保存类的实际类型,只保存类本身。如果我错了,请纠正我。@akaltar我也从未使用过它,它从链接中保存类的类型并在反序列化过程中重建它们。我希望看到一个工厂实现,在那里我可以动态添加类型,如
factory.AddType(int,“int”);
。如果您能提供,我会接受这个答案,因为它比使用boost更简单。@akaltar:添加了工厂示例。
#include <map>
#include <string>
#include <iostream>
#include <QSharedPointer>
#include <utility>

typedef std::string ClassId;
typedef std::ostream OutStream;

class Serializeable{
protected:
    virtual void saveData(OutStream &out) = 0;
public:
    virtual ClassId getClassId() const = 0;
    void save(OutStream &out){
        out << getClassId();
        saveData(out);
    }
    virtual ~Serializeable(){
    }
};

class Derived: public Serializeable{
protected:
    virtual void saveData(OutStream &out){
        out << "test";
    }
public:
    virtual ClassId getClassId() const{
        return "Derived";
    }
};

typedef QSharedPointer<Serializeable> SerializeablePtr; //basically std::shared_ptr

SerializeablePtr makeDerived(){
    return SerializeablePtr(new Derived());
}

class ClassFactory{
protected:
    typedef SerializeablePtr (*BuilderCallback)();
    typedef std::map<ClassId, BuilderCallback> BuilderMap;
    BuilderMap builderMap;

    template<class C> static SerializeablePtr defaultBuilderFunction(){
        return SerializeablePtr(new C());  
    }

public:
    SerializeablePtr buildClass(ClassId classId){
        BuilderMap::iterator found = builderMap.find(classId);
        if (found == builderMap.end())
            return SerializeablePtr();//or throw exception

        return (*(found->second))();
    }

    void registerClass(ClassId classId, BuilderCallback callback){
        builderMap[classId] = callback;
    }
    template<typename T> void registerClassByValue(const T &val){
        registerClass(val.getClassId(), ClassFactory::defaultBuilderFunction<T>);
    }
    template<typename T> void registerClassWithTemplate(ClassId classId){
        registerClass(classId, ClassFactory::defaultBuilderFunction<T>);
    }
};


int main(int argc, char** argv){
    ClassFactory factory;

    std::string derivedId("Derived");
    factory.registerClass(derivedId, makeDerived);
    SerializeablePtr created = factory.buildClass(derivedId);
    created->save(std::cout);
    std::cout << std::endl;

    Derived tmp;
    factory.registerClassByValue(tmp);
    created = factory.buildClass(derivedId);
    created->save(std::cout);
    std::cout << std::endl;

    factory.registerClassWithTemplate<Derived>(derivedId);
    created = factory.buildClass(derivedId);
    created->save(std::cout);
    std::cout << std::endl;
    return 0;
}