C++反射的一種實現(xiàn)方法詳解
一、注冊輔助類
ClassRegistry:模板函數(shù),用于data、module、contextdata的注冊,其中的函數(shù)解析:
create_object:從RegistryMap里找到傳入name對應的RegistryNode(RegistryNode保存了名字和構(gòu)造函數(shù)),調(diào)用構(gòu)造函數(shù)返回。
register_class:用傳入的name和constructor注冊RegistryMap,只在Register的構(gòu)造函數(shù)里面調(diào)用,后面會在ClassRegister<IData> DataRegister、ClassRegister<IModule> ModuleRegister、ClassRegister<IContextData> ContextDataRegister用到。RegistryMap里面的數(shù)據(jù)是從register_class這個方法插入數(shù)據(jù)進去的,后面會在IMPLEMENT_XXX中調(diào)用到這個。
fill_name_array:找到RegistryMap里面注冊的name,插入傳入?yún)?shù)。
二、使用到的宏定義
2.1 data
REGISTER_DATA:聲明構(gòu)造data_class的函數(shù) __construct_##name##_data() ,其中調(diào)用了data_calss的構(gòu)造函數(shù);
聲明獲取class的get_##name,函數(shù)體的get_data從 sign_data_map里面獲取到對應的IData
#define REGISTER_DATA(data_class, name) \
inline ::wmf::IData* __construct_##name##_data() { return new data_class; } \
namespace wmf { \
namespace internal { \
inline data_class* get_##name() { return get_data<data_class>(#name); } \
} \
} // wmf::internal
IMPLEMENT_DATA:調(diào)用DataRegister的構(gòu)造函數(shù)。聲明變量__##name##_module_register,這里會將輸入的name和構(gòu)造函數(shù)__construct_##name##_data注冊到RegistryMap中;
#define IMPLEMENT_DATA(name) \ ::wmf::internal::DataRegister __##name##_module_register( \ #name, __construct_##name##_data)
使用:
在需要用到的.cpp文件的的.h文件的位置調(diào)用REGISTER_DATA,聲明構(gòu)造函數(shù)和獲取data的get_xxx函數(shù)。
在每個service的cpp文件視線中調(diào)用IMPLEMENT_DATA,注入RegistryMap。
在每個service的cpp文件的InitInjection中,INJECT_DATA_MODULE_DEPENDENCY把這個詞典注入到module中。
2.2 module
REGISTER_MODULE:聲明__construct_#name##_module(),返回new module_class;
聲明獲取class的get_##name,函數(shù)體里面返回ModuleMap中保存的對象(cast_module從ModuleMap里面找到其對應的對象,如果找不到,則從RegisterMap里面找到其構(gòu)造函數(shù),并調(diào)用create_object之后插入ModuleMap,并返回新建的對象(RegisterMap里面的數(shù)據(jù)從IMPLEMENT_XXX來的))
#define REGISTER_MODULE(module_class, name) \
inline ::wmf::IModule* __construct_##name##_module() { \
return new module_class; \
} \
namespace wmf { \
namespace internal { \
inline module_class* get_##name(::wmf::Context& ctx) { \
return ctx.cast_module<module_class>(#name); \
} \
} \
} // wmf::internal
IMPLEMENT_MODULE:聲明__##name##_module_register變量,以插入RegistryMap。
#define IMPLEMENT_MODULE(name) \ ::wmf::internal::ModuleRegister __##name##_module_register( \ #name, __construct_##name##_module)
使用:
在新增module的.h文件最后調(diào)用REGISTER_MODULE聲明了在IMPLEMENT_MODULE中會用到的構(gòu)造函數(shù),以及聲明了從ModuleMap中獲取其對象的get_xxx函數(shù)。
在service的最后調(diào)用IMPLEMENT_MODULE,把module注冊到RegistryMap中。
2.3 context data
REGISTER_CONTEXT_DATA:聲明__construct_##name##_context_data(),新建data_class;
聲明獲取class的get_##name,函數(shù)體里面通過name查找到ContextDataMap保存的名字簽名對應的IContextData,轉(zhuǎn)換為data_class返回。
#define REGISTER_CONTEXT_DATA(data_class, name) \
inline ::wmf::IContextData* __construct_##name##_context_data() { \
return new data_class; \
} \
namespace wmf { \
namespace internal { \
inline data_class* get_##name(const ::wmf::Context& ctx) { \
return ctx.cast_context_data<data_class>(#name); \
} \
} \
} // wmf::internal
IMPLEMENT_CONTEXT_DATA:聲明__##name##_context_data變量,這里會將輸入的name和構(gòu)造函數(shù)__construct_##name##_context_data注冊到RegistryMap中;
#define IMPLEMENT_CONTEXT_DATA(name) \ ::wmf::internal::ContextDataRegister __##name##_context_data( \ #name, __construct_##name##_context_data)
2.4 index_data
DECLARE_INDEX_DATA:N for name, VT for VersionIndex 類型。聲明類型C為用類型VT組裝,path、name、desc用N組裝的VIAdaptor類型。
#define DECLARE_INDEX_DATA(VT, C, N) \
extern const char __index_##N##_path[]; \
extern const char __index_##N##_name[]; \
extern const char __index_##N##_desc[]; \
typedef wmf::VIAdaptor<argument_type<void(VT)>::type, __index_##N##_path, \
__index_##N##_name, __index_##N##_desc> \
C
DEFINE_INDEX_DATA:N for name,這里是聲明一堆string變量,用于data的path、name、desc。
#define DEFINE_INDEX_DATA(N) \ const char __index_##N##_path[] = #N "_path"; \ const char __index_##N##_name[] = #N "_name"; \ const char __index_##N##_desc[] = #N "_desc"; \ DEFINE_string(N##_path, "", "index " #N " path"); \ DEFINE_string(N##_name, "", "index " #N " name"); \ DEFINE_string(N##_desc, "index_" #N, "index " #N " desc")
2.5 injection
DEFINE_INJECTION:定義一個把object_ref變量設置為class_type*類型的傳入變量的函數(shù)。
#define DEFINE_INJECTION(injection_name, class_type, object_ref) \
void set_##injection_name(class_type* module) { object_ref = module; }
INJECT_OBJECT_OBJECT_DEPENDENCY:調(diào)用object_to這個對象的set_##injection_name方法,傳入?yún)?shù)是object_from的引用。結(jié)合DEFINE_INJECTION就是把object_from設置到object_to這個對象里面。
#define INJECT_OBJECT_OBJECT_DEPENDENCY(injection_name, object_from, \
object_to) \
(object_to).set_##injection_name(&(object_from))
INJECT_MODULE_DEPENDENCY:在上下文context中找到module_from的變量,注入到同一個上下文的module_from里面。
#define INJECT_MODULE_DEPENDENCY(injection_point, context, module_from, \
module_to) \
::wmf::internal::get_##module_to(context)->set_##injection_point( \
::wmf::internal::get_##module_from(context));
INJECT_DATA_MODULE_DEPENDENCY:把data注入到通過上下文context獲取的module_to中。
#define INJECT_DATA_MODULE_DEPENDENCY(injection_point, context, data, \
module_to) \
::wmf::internal::get_##module_to(context)->set_##injection_point( \
::wmf::internal::get_##data());
INJECT_MODULE_OBJECT_DEPENDENCY:通過上下文context獲取的module_from注入到object_to中。
#define INJECT_MODULE_OBJECT_DEPENDENCY(injection_point, context, module_from, \
object_to) \
(object_to).set_##injection_point( \
::wmf::internal::get_##module_from(context));
INJECT_OBJECT_MODULE_DEPENDENCY :object_from注入到通過上下文獲取的module_to中。
#define INJECT_OBJECT_MODULE_DEPENDENCY(injection_point, context, object_from, \
module_to) \
::wmf::internal::get_##module_to(context)->set_##injection_point( \
&(object_from))
使用:
在上下文相關的session中調(diào)用INJECT_MODULE_DEPENDENCY、INJECT_DATA_MODULE_DEPENDENCY;
INJECT_MODULE_DEPENDENCY用于把session相關的信息(比如session_docs、request、response)注入到module中,module的意思是這個請求需要過的模塊名。
INJECT_DATA_MODULE_DEPENDENCY用于把data注入到module中。
三、總結(jié)
3.1 新增一個module
在新增module的.h文件最后調(diào)用REGISTER_MODULE聲明了在IMPLEMENT_MODULE中會用到的構(gòu)造函數(shù),以及聲明了從ModuleMap中獲取其對象的get_xxx函數(shù)。
在service的最后調(diào)用IMPLEMENT_MODULE,把module注冊到RegistryMap中。
在上下文相關的session中調(diào)用INJECT_MODULE_DEPENDENCY、INJECT_DATA_MODULE_DEPENDENCY;
INJECT_MODULE_DEPENDENCY用于把session相關的信息(比如session_docs、request、response)注入到module中,module的意思是這個請求需要過的模塊名。
INJECT_DATA_MODULE_DEPENDENCY用于把data注入到module中。
3.2 代碼回顧
ClassRegistry用于給第二項的一堆宏使用。module于類的映射關鍵在于RegistryMap,新增一個module的時候,服務會去RegistryMap里面找名字對應的構(gòu)造函數(shù)。RegistryMap里面的數(shù)據(jù)是在IMPLEMENT_MODULE的時候注入進來的name和類的對應關系。配置文件里面配的是module的鏈條,比如需要過AModule,BModule,這時候就在init的時候把所有module都插進去,然后在schedule_impl里面調(diào)用每個module的run函數(shù)。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支持。
欄 目:C語言
下一篇:OpenCV實現(xiàn)輪廓的發(fā)現(xiàn)
本文標題:C++反射的一種實現(xiàn)方法詳解
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/279.html
您可能感興趣的文章
- 04-02c語言的正則匹配函數(shù) c語言正則表達式函數(shù)庫
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對數(shù)怎么表達
- 04-02c語言沒有round函數(shù) round c語言
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 01-10c語言求1+2+...+n的解決方法
- 01-10求子數(shù)組最大和的解決方法詳解
- 01-10深入理解約瑟夫環(huán)的數(shù)學優(yōu)化方法
- 01-10深入二叉樹兩個結(jié)點的最低共同父結(jié)點的詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設計- 解析最少換車次數(shù)的問題詳解
- 01-10c語言 跳臺階問題的解決方法


閱讀排行
本欄相關
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 04-02jquery與jsp,用jquery
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10C#中split用法實例總結(jié)


