由映射驱动的工厂类,用于确定对象类型

时间:2015-05-17 18:37:09

标签: c++ factory-pattern

我有一个大脑冻结,无法弄清楚如何最好地解决这个问题。我通过调用

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

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

ITERATION:     CrateEnvironment≤(*它)GT(世界);

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

祝你好运

1 个答案:

答案 0 :(得分:1)

对于每个类,您可以使用一个函数作为生成器并创建一个新对象并返回指向它的指针(或更好的是,shared_ptr)。

然后在容器中存储生成器函数指针。

逐步解释:

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

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>(); 
};

这将作为您的&#34;类型&#34;的替代品。容器(为了简化示例我使用了矢量,但您可以轻松选择地图):

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

然后你可以像这样填充你的宇宙,而不用任何if:

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%的狼人。