[C++] Class工廠

Class工廠本質

本質爲實現一個Map,在程序的main函數運行前將能夠生成各種實例的函數放到此Map中(即「註冊」),總接下來須要一下幾個條件:c++

  • 實現一個Map,此Map在各註冊邏輯運行前被初始化
  • 爲每一個類實現一個生成函數,用於建立並返回各種的實例
  • 將生成函數加入到Map中發生在main函數執行前

同時,請注意本例子中,被註冊的函數須要具有相同的構造函數函數

功能實現

首先實現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);
相關文章
相關標籤/搜索