详解 class Register

class Register
{
public:
	Register(const wstring &Class, int ModuleType, wstring Name, wstring Desc, CREATECLASS_FUNC CreateFunc, const PARAMINFO* ParamInfo,int nParamInfo)
	{
		CLASSINFO ClassInfo = { ModuleType,Name, Desc,CreateFunc ,ParamInfo ,nParamInfo };
		DynObjectFactory::Register(Class, ClassInfo);
	}
};


#define REGISTER_CLASS(Class) \
class Class##Register { \
public: \
     static  void* NewInstance() \
    { \
         return  new Class; \
    } \
private: \
     static Register reg_; \
}; \
Register Class##Register::reg_(_T(#Class),int(Class##_ModuleType),Class##_Name,Class##_Desc, Class##Register::NewInstance,Class##_Params,sizeof(Class##_Params)/sizeof(PARAMINFO))

我们来逐步解析并详细说明这个宏 REGISTER_CLASS 的工作原理,包括其实现和目的。


宏展开后的实际代码

假设宏 REGISTER_CLASS(MyClass) 展开后,将生成以下代码:

class MyClassRegister {
public:
    // 这是一个静态函数,负责创建 MyClass 类的实例。
    static void* NewInstance() {
        return new MyClass;
    }

private:
    // 静态 Register 对象,用于在构造时自动注册 MyClass 的信息。
    static Register reg_;
};

// 定义静态成员 reg_,并通过构造函数初始化它。
// 传递 MyClass 的元信息给注册系统(DynObjectFactory)。
Register MyClassRegister::reg_(
    _T("MyClass"),                             // 类名
    int(MyClass_ModuleType),                   // 模块类型
    MyClass_Name,                              // 名称
    MyClass_Desc,                              // 描述
    MyClassRegister::NewInstance,              // 用于创建实例的函数指针
    MyClass_Params,                            // 参数信息数组
    sizeof(MyClass_Params) / sizeof(PARAMINFO) // 参数数量
);

每一部分的目的与作用

1. 宏定义的目的

REGISTER_CLASS 的主要目的是 动态注册类的信息,并将该类的相关信息传递给一个全局的工厂类 DynObjectFactory,实现类似反射的机制。

使用这个宏后,DynObjectFactory 就能够在运行时动态创建类实例、获取类元信息(如名称、描述、参数信息等)。


2. 宏内代码的每一步解析
2.1. 创建一个用于注册的辅助类
class MyClassRegister {

这个类 MyClassRegister 是为目标类(如 MyClass)服务的辅助类。它的唯一目的是在静态对象初始化阶段,自动注册 MyClass 的信息到 DynObjectFactory


2.2. 静态方法 NewInstance
static void* NewInstance() {
    return new MyClass;
}
  • 这是一个静态方法,用于 动态创建目标类的实例
  • 它的返回值是 void*,这是为了与通用的工厂机制兼容,避免直接绑定到特定类的类型。
  • 在运行时,如果 DynObjectFactory 需要创建 MyClass 的实例,就会调用这个静态方法。

2.3. 静态成员 reg_
static Register reg_;
  • 这是一个静态成员,类型是 Register
  • 静态成员的初始化是在全局或文件级作用域内发生的,因此在程序启动时就会执行它的构造函数。
  • reg_ 的构造函数会调用 DynObjectFactory::Register,从而完成类信息的注册。

2.4. 定义并初始化静态成员
Register MyClassRegister::reg_(
    _T("MyClass"),                             // 类名
    int(MyClass_ModuleType),                   // 模块类型
    MyClass_Name,                              // 名称
    MyClass_Desc,                              // 描述
    MyClassRegister::NewInstance,              // 创建实例的函数
    MyClass_Params,                            // 参数信息
    sizeof(MyClass_Params) / sizeof(PARAMINFO) // 参数数量
);
  • 类名:传递目标类的字符串形式 _T("MyClass")
  • 模块类型:通常是枚举值或常量,表示类所属的模块。
  • 名称、描述:提供类的更详细的元信息,便于工厂或框架进行描述。
  • NewInstance:将创建实例的函数指针传递给注册系统,以便支持动态实例化。
  • 参数信息:提供类的参数元信息,便于在运行时对参数进行校验、动态设置等。
  • 参数数量:计算参数数组的大小,避免硬编码。

3. Register 类的作用

Register 类的构造函数如下:

Register(const wstring &Class, int ModuleType, wstring Name, wstring Desc, CREATECLASS_FUNC CreateFunc, const PARAMINFO* ParamInfo, int nParamInfo) {
    CLASSINFO ClassInfo = { ModuleType, Name, Desc, CreateFunc, ParamInfo, nParamInfo };
    DynObjectFactory::Register(Class, ClassInfo);
}
  • 输入参数:接收类的名称、模块类型、描述、创建函数和参数信息。
  • 封装信息:将这些信息封装到 CLASSINFO 结构体中。
  • 注册工厂:调用 DynObjectFactory::Register,将类信息添加到工厂类中。

这一步的核心作用是将目标类的所有元信息注册到一个全局的工厂对象中。


4. DynObjectFactory 的作用

DynObjectFactory 是一个全局工厂类,通常用来管理所有动态注册的类信息。它的典型职责包括:

  • 动态创建类实例:通过类名和 NewInstance 函数指针,动态生成类的实例。
  • 查询类信息:通过类名查询描述、模块类型、参数信息等。
  • 反射机制:为框架提供类似反射的能力,支持动态加载模块或插件。

总结

整个流程通过 REGISTER_CLASS 宏实现了以下功能:

  1. 静态注册目标类:在程序启动时,目标类的元信息被自动注册到 DynObjectFactory
  2. 动态实例化支持:通过 NewInstance 函数,支持在运行时动态创建目标类的实例。
  3. 元信息管理:为目标类提供名称、描述、参数信息等元信息,便于框架或系统进行统一管理。
  4. 代码简化:开发者只需调用 REGISTER_CLASS(MyClass),即可完成复杂的注册工作,避免重复代码。

适用场景

  • 插件框架
  • 动态模块加载
  • 脚本引擎集成
  • 类反射与动态实例化

如果还有不明白的部分,请继续提问!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七贤岭↻双花红棍↺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值