Factory class 由用于确定对象类型的映射驱动

Factory class driven by a map for determining the object type

我脑子发呆了,不知道如何最好地解决这个问题。我正在通过调用

从我的工厂 class 创建对象
CreateEnvironment<T>(ARGS);

现在假设我想将很多 class 类型保存到地图中并遍历地图并在运行时调用方法,如下所示:

迭代: CrateEnvironment<(*it)>(世界);

(*it) 应该是 class 类型,例如可以是 FOO 或 BAR。我如何实现这一点而不是有很多 if 语句?

此致

对于每个 class 你可以有一个函数作为生成器并创建一个新对象和 return 一个指向它的指针(或者更好的是 shared_ptr)。

然后您可以在您的容器中存储生成器函数指针。

分步说明:

假设您有这些 classes 来填充您的世界:

struct GO { virtual void say_hello()=0; };  // Game Object
struct A:GO { void say_hello() { cout<<"I'm a werewolf\n";} };
struct B:GO { void say_hello() { cout<<"I'm a soldier\n";}};

然后您可以定义一个通用的 GO 生成器:

template <class T> 
shared_ptr<GO> generator() {
    return make_shared<T>(); 
};

这将作为您的“类型”容器的替代品(为简单起见,我使用了矢量,但您可以轻松选择地图):

typedef shared_ptr<GO> (*gen_fn)();
vector <gen_fn> generators{generator<A>, generator<B>};

然后你可以像这样填充你的宇宙,没有任何如果:

vector<shared_ptr<GO>> universe; 

default_random_engine generator;
uniform_int_distribution<int> distribution(0,generators.size()-1);

for (int i=0; i<10; i++) {   
    int mytype = distribution(generator); 
    universe.push_back(generators[mytype]()); 
}

for (auto x: universe) 
    x->say_hello(); 

还有一个 online demo.

统计备注:由于分布均匀,你大概率会得到每种物品比例大致相同的物品。如果你想要不同的分布,你可以多次添加相同类型的生成器。例如,generators{generator<A>, generator<B>, generator<B>}; 你会有大约 66% 的士兵和 33% 的狼人。