gpt4 book ai didi

c++ - 在文件中存储类的类型

转载 作者:行者123 更新时间:2023-11-28 03:07:32 25 4
gpt4 key购买 nike

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

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

我正在考虑存储派生类的 typeid 并保留 Node 可以派生到的可能类型的列表,但我不知道如何我能做到吗?

性能不是问题,无论如何我们谈论的是 <100 个节点。答案应该适用于 windows、linux 和 mac os 的多平台。我想要的答案是在不更改 NodeManager 代码的情况下,尽可能轻松地添加更多节点类型。

最佳答案

在基类中,创建返回某种“ID”的抽象虚方法。 (字符串、整数、枚举等等)。

在“保存”方法中,首先为所有类写入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);
}
};

创建一个工厂,根据其 ID 构造所需的类。

--编辑--

工厂示例(C++03 标准):

#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;
}

QSharedPointer 是 Qt 4 的智能指针类,大致相当于 std::shared_ptr。在您的代码中使用 std::shared_ptrboost::shared_ptr 而不是 QSharedPointer

关于c++ - 在文件中存储类的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19335604/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com