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);
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/308457.html
標籤:設計模式
上一篇:23種設計模式總結
下一篇:設計模式筆記(二):策略模式
