这一部分宏定义代码看不懂,请问能解读一下吗?另外有哪些地方可以系统的学习这些宏定义?好多C++的书上都没有讲。
欢迎选择我的课程,让我们一起见证您的进步~~
其实这个宏的名称已经很大程度上表述清楚了其作用:在程序启动时自动向GameServerModuleMgr注册某个模块,这实际上是实现了一种静态的插件系统。
不难揣测,该宏的用法应该类似下面这个样子:
class MyModuleA : public AbstractModule { blah... }; REG_GAMESERVER_MODULE(MyModuleA);
系统有一个全局唯一的GameServerModuleMgr单例,我们可以通过GameServerModuleMgr::getInstance()获取其实例。而所谓的注册模块,也即是调用该类的regModule,并将待注册的类的实例传入。即:
GameServerModuleMgr::getInstance()
GameServerModuleMgr::getInstance()->regModule(new MyModuleA());
剩下的问题是,我们通常不想在main函数(或者我们的初始化代码中)为我们的每一个Module手动地向GameServerModuleMgr注册,于是我们需要一种自动的方式。考虑到在C++里,全局对象的构造函数是在main执行前自动被CRT执行的,所以我们可以构造如下的类:
struct REG_MyModuleA { REG_MyModuleA() { GameServerModuleMgr::getInstance()->regModule(new MyModuleA()); } }; # 创建全局对象,最终导致MyModuleA被自动注册(通过其构造函数) # 声明为static避免该对象被其他代码访问到 (Translation Unit Private) static REG_MyModuleA sg_ REG_MyModuleA;
REG_MyModuleA对我们程序的来说并没有功能上的意义,它的作用仅仅是使上述自动注册过程能够发生而已。而那个宏所做的,无非是把这里的MyModuleA替换成一个可变的宏参数,从而提供给Module作者们一个handy的helper而已。关于具体的语法(##粘黏符等等)上面的同学已经说得很清楚了,我这里就不赘述了。
这个宏的作用:每次使用宏的时声明一个新的struct,并声明一个该类型的静态对象。譬如 REG_GAMESERVER_MODULE(ABC) 等同于:
REG_GAMESERVER_MODULE(ABC)
struct REG_ABC { REG_ABC(){ //some stuff } }; static REG_ABC object;
好处: 少打字,添加同类型新模块少费功夫缺点: 缺点很多就不列举了, 搜索引擎都能搜到一大片。
我的理解是:
1.宏定义是一种字符直接替换
2.#和##用于 参数的字符串化
举个栗子:
#define TEST(arg) int test_##arg; #define TEST2(arg) int #arg;
调用:
TEST(val); -> int test_val; TEST2(val);-> int val;
#用于取参数字符值,##用于连接参数字符值
所以在代码中调用:
REG_GAMESERVER_MODULE(cls);
就在原地替换成:
struct REG_cls; ... static REG_cls sg_REG_cls;
然后看替换的代码,应该是根据参数cls声明一个Struct REG_cls,然后实现它的构造函数。最后声明一个对应的static变量。
其实这个宏的名称已经很大程度上表述清楚了其作用:在程序启动时自动向GameServerModuleMgr注册某个模块,这实际上是实现了一种静态的插件系统。
不难揣测,该宏的用法应该类似下面这个样子:
系统有一个全局唯一的GameServerModuleMgr单例,我们可以通过
GameServerModuleMgr::getInstance()
获取其实例。而所谓的注册模块,也即是调用该类的regModule,并将待注册的类的实例传入。即:GameServerModuleMgr::getInstance()->regModule(new MyModuleA());
剩下的问题是,我们通常不想在main函数(或者我们的初始化代码中)为我们的每一个Module手动地向GameServerModuleMgr注册,于是我们需要一种自动的方式。考虑到在C++里,全局对象的构造函数是在main执行前自动被CRT执行的,所以我们可以构造如下的类:
REG_MyModuleA对我们程序的来说并没有功能上的意义,它的作用仅仅是使上述自动注册过程能够发生而已。而那个宏所做的,无非是把这里的MyModuleA替换成一个可变的宏参数,从而提供给Module作者们一个handy的helper而已。关于具体的语法(##粘黏符等等)上面的同学已经说得很清楚了,我这里就不赘述了。
这个宏的作用:每次使用宏的时声明一个新的struct,并声明一个该类型的静态对象。
譬如
REG_GAMESERVER_MODULE(ABC)
等同于:好处: 少打字,添加同类型新模块少费功夫
缺点: 缺点很多就不列举了, 搜索引擎都能搜到一大片。
我的理解是:
1.宏定义是一种字符直接替换
2.#和##用于 参数的字符串化
举个栗子:
调用:
#用于取参数字符值,##用于连接参数字符值
所以在代码中调用:
就在原地替换成:
然后看替换的代码,应该是根据参数cls声明一个Struct REG_cls,然后实现它的构造函数。最后声明一个对应的static变量。