#ifndef INC_MODULE_FACTORY2_H
#define INC_MODULE_FACTORY2_H
#include <string>
#include <map>
#include <functional>
#include <utility> // std::pair
#include <iostream> // std::cout
#define MODULE_REG(class_name,id,desc) \
namespace ascendBaseModule { \
class class_name##Reg { \
public: \
class_name##Reg() \
{ \
ModuleFactory1::RegisterModule(#id, #desc, class_name##Reg::CreatObjFunc); \
} \
static void *CreatObjFunc() \
{ \
return new class_name; \
} \
}; \
static class_name##Reg class_name##helper;\
}
namespace ascendBaseModule {
using Starter = std::function<void *()>;
/*
** 对象工厂不保存对象,保存的是对象的构造器,因为对象工厂不是对象池,而是
** 对象的生产者,允许不断的创建实例,这样做也实现了对象延迟创建。本质上是
** 通过宏来定义了很多全局的静态变量,这些静态变量是为了实现自动注册。
** 参考:https://www.cnblogs.com/qicosmos/p/5090159.html
*/
// by zjx, 添加 id 和 desc
class ModuleFactory1
{
public:
static void RegisterModule(std::string id, std::string desc, Starter constructor)
{
Starters()[id] = std::make_pair(constructor, desc);
}
static void *MakeModule(const std::string &id)
{
if(Starters().empty())std::cout << "Starters is empty ..." << std::endl;
auto itr = Starters().find(id);
if (itr == Starters().end())
{
std::cout << "MakeModule fail ..." << std::endl;
return nullptr;
}
std::cout << "MakeModule id = " << id
<< " , desc = " << itr->second.second
<< std::endl;
return ((Starter)itr->second.first)();
}
private:
inline static std::map<std::string, std::pair<Starter, std::string>> &Starters()
{
static std::map<std::string, std::pair<Starter, std::string>> instance;
return instance;
}
};
}
#endif
1,某个类的头文件在编译阶段,通过注册接口调用了注册宏:MODULE_REG(Tester, Tester1688 ,512x512 class-2)
2,注册宏展开是一个类,创建了指向自己的类:static class_name##Reg class_name##helper;
3,因为第2步的类创建,执行构造函数:class_name##Reg()
4,构造函数里,通过执行内部函数:static void *CreatObjFunc() ,返回注册类的构造器指针。
5,构造函数里,返回的构造器指针作为参数,传递给了外部一个模块工厂:ModuleFactory1::RegisterModule,外部模块工厂会用一个map容器把这个构造器指针和相关的信息保存起来,这些信息保存在执行文件里面。
6,执行程序的时候,通过注册类的信息调用ModuleFactory1::MakeModule,函数里面 ((Starter)itr->second.first)();执行类构造并且返回一个类对象。至此生产出了一个类对象。
以上是个人的摸索和理解,特此记录!