将ID号映射到类

时间:2011-11-06 23:12:41

标签: c++ class

我正在建立一个系统,我可以根据从文件中读取的一些信息动态实例化类。所以,这必须在运行时完成。有问题的类是多态的,都来自CBaseTheoryEnt类。我想要做的是将ID号与每个类相关联(例如,使用无序映射)。本质上,我的管理类将查看从输入文件中读入的一系列这些ID号,然后实例化相应的类。将类与ID相关联然后根据输入实例化它们的理想和有效方法是什么?

2 个答案:

答案 0 :(得分:7)

执行此操作的一种方法是使用模板函数来实例化CBaseTheoryEnt的子类:

template<typename T>
CBaseTheoryEnt* instantiator() {
    return new T;
}

然后为从hash_map派生的每个类都有一个CBaseTheoryEnt或这些函数的数组,并让该类的键与它的实例化器相关联。然后,当您索引数组或映射时,您将获得一个函数,该函数在被调用时将返回指向相应类的实例的指针。

例如,如果您有A,B和C类,并且A的ID为0,则B为1,C为2,您将拥有:

typedef CBaseTheoryEnt* (*instantiator_ptr)();
instantiator_ptr classes[] = {
    &instantiator<A>,
    &instantiator<B>,
    &instantiator<C>
};

然后像

一样使用它
int idx = get_class_id();

CBaseTheoryEnt* inst = classes[idx]();

答案 1 :(得分:1)

你没有提供太多的细节,所以这是一个使用map可能适用的相当一般的方法:

struct Base
{
  virtual int ID() const = 0;
  // ...
};

typedef Base * (*create_fp)();
typedef std::map<int, create_fp> create_map;

class DerivedA : public Base { /* ... */ };
class DerivedB : public Base { /* ... */ };
class DerivedC : public Base { /* ... */ };

namespace BaseCreators
{
  DerivedA * makeA() { /* ... */ }
  DerivedB * makeA() { /* ... */ }
  DerivedC * makeA() { /* ... */ }
}

const create_map creators {
  { 1, BaseCreators::makeA },
  { 2, BaseCreators::makeB },
  { 3, BaseCreators::makeC }
};

int main()
{
  int a = get_id_from_user();
  create_fp cr = creators.find(a)->second; // or check for existence first
  Base * b = cr();
}

(如果您没有C ++ 11,则必须使creators映射非常量并手动填充。)