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

标签 c++ factory-pattern

我的大脑卡住了,想不出如何最好地解决这个问题。我正在通过调用

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

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

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

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

最好的问候

最佳答案

对于每个类,您都可以有一个函数来充当生成器并创建一个新对象并返回指向它的指针(或者更好的是,一个 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>(); 
};

这将作为您的“类型”容器的替代品(为了示例的简单性,我使用了 vector ,但您可以轻松地选择 map ):

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

关于c++ - 由映射驱动的工厂类,用于确定对象类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30290650/

相关文章:

c++ - 我的以下断言是否正确?

c++ - 如何从 C/C++ 不带控制台窗口执行批处理文件?

constructor - 关于 Dart 中的工厂构造函数

java - 工厂模式: How to access properties of concrete product classes from client?

javascript - TypeScript 工厂模式表示属性不存在

c# - 通过 lambda 工厂与直接 "new Type()"语法创建对象

c++自定义字符串格式使用stringstreams

c++ - 如何使用 unistd.h 中的 **environ 来搜索正确的路径?

C++:在方法中创建对象并在方法外使用它

java - 工厂模式方法范围