本质为实现一个Map,在程序的main函数运行前将能够生成各种实例的函数放到此Map中(即“注册”),总接下来须要一下几个条件:c++
同时,请注意本例子中,被注册的函数须要具有相同的构造函数函数
首先实现Map类:code
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
,其返回一个其内部的静态变量。get
为了便捷的实现函数的注册,在此处实现一个宏:string
#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
文件中使用。对于以下类的注册会出现错误:class
STEP_REGISTER("Add", Add<int>);
此处建议应使用:变量
using AddInt = Add<int>; STEP_REGISTER("AddInt", AddInt);