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
宏实现了以下功能:
- 静态注册目标类:在程序启动时,目标类的元信息被自动注册到
DynObjectFactory
。 - 动态实例化支持:通过
NewInstance
函数,支持在运行时动态创建目标类的实例。 - 元信息管理:为目标类提供名称、描述、参数信息等元信息,便于框架或系统进行统一管理。
- 代码简化:开发者只需调用
REGISTER_CLASS(MyClass)
,即可完成复杂的注册工作,避免重复代码。
适用场景:
- 插件框架
- 动态模块加载
- 脚本引擎集成
- 类反射与动态实例化
如果还有不明白的部分,请继续提问!