本質爲實現一個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);