[C++] Class工厂
Class工厂本质
本质为实现一个Map,在程序的main函数运行前将可以生成各类实例的函数放到此Map中(即“注册”),总接下来需要一下几个条件:
- 实现一个Map,此Map在各注册逻辑运行前被初始化
- 为每个类实现一个生成函数,用于创建并返回各类的实例
- 将生成函数加入到Map中发生在main函数执行前
同时,请注意本例子中,被注册的函数需要具备相同的构造函数
功能实现
首先实现Map类:
class StepFactory {
public:
StepFactory(std::string name, StepPtr_t fp) { StepFactory::registerStep(name, fp); }
static IStep* getInstance(std::string name, IStepArgs args) {
if (getMap().find(name) == getMap().end()) {
ERROR_LOG(name << " not found");
return nullptr;
}
return getMap()[name](args);
}
static void registerStep(std::string name, StepPtr_t fp) {
getMap().insert(std::make_pair(name, fp));
INFO_LOG("Register: " << name);
}
static classObjMap_t& getMap() {
static classObjMap_t map;
return map;
}
};
其中可见,此例中被注册的函数基类是IStep
,构造参数均为IStepArgs
,除了提供了从Map中取数据,以及向Map中加入数据外,使用一个类静态函数getMap
,其返回一个其内部的静态变量。
为了便捷的实现函数的注册,在此处实现一个宏:
#define STEP_REGISTER(name, cls) \
IStep* pluginRegistrar##cls##fun(IStepArgs args) { return new cls(args); } \
static StepFactory pluginRegistrar##cls(name, pluginRegistrar##cls##fun);
宏内首先定义了一个与类名相关的函数,函数内部是创建此类的实例;同时定义了一个StepFactory
变量,此变量也是与类名字相关的,此变量调用了构造函数,实现了类的生成函数向Map添加的过程。由此可见,此宏需要在.cpp
文件中使用。对于如下类的注册会出现错误:
STEP_REGISTER("Add", Add<int>);
此处建议应使用:
using AddInt = Add<int>;
STEP_REGISTER("AddInt", AddInt);
热门相关:骑士归来 惊世毒妃:轻狂大小姐 惊世毒妃:轻狂大小姐 战神 大神你人设崩了