[C++] Class工厂

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);

热门相关:骑士归来   惊世毒妃:轻狂大小姐   惊世毒妃:轻狂大小姐   战神   大神你人设崩了