c++类动态注册摸索与理解

#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)();执行类构造并且返回一个类对象。至此生产出了一个类对象。

以上是个人的摸索和理解,特此记录!

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值