大家讲道理2017-04-17 13:59:11
其實這個巨集的名稱已經在很大程度上表述清楚了其作用:在程式啟動時自動向GameServerModuleMgr註冊某個模組,這其實是實作了一種靜態的插件系統。
不難揣測,該宏的用法應該類似下面這個樣子:
class MyModuleA : public AbstractModule {
blah...
};
REG_GAMESERVER_MODULE(MyModuleA);
系統有一個全域唯一的GameServerModuleMgr單例,我們可以透過GameServerModuleMgr::getInstance()
取得其實例。而所謂的註冊模組,也即是呼叫該類別的regModule,並將待註冊的類別的實例傳入。即:
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而已。關於具體的文法(##黏黏符等等)上面的同學已經說得很清楚了,我這裡就不贅述了。
PHPz2017-04-17 13:59:11
這個巨集的作用:每次使用巨集的時宣告一個新的struct,並宣告一個該型別的靜態物件。
譬如 REG_GAMESERVER_MODULE(ABC)
等同於:
struct REG_ABC
{
REG_ABC(){
//some stuff
}
};
static REG_ABC object;
好處: 少打字,加入同類型新模組少費功夫
缺點: 缺點很多就不列舉了, 搜尋引擎都能搜到一大片。
PHP中文网2017-04-17 13:59:11
我的理解是:
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變數。