[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);
相关文章
相关标签/搜索