84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
这一部分宏定义代码看不懂,请问能解读一下吗?另外有哪些地方可以系统的学习这些宏定义?好多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变量。