如何在C++中實(shí)現(xiàn)反射-創(chuàng)新互聯(lián)

本篇文章為大家展示了如何在C++中實(shí)現(xiàn)反射,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)是網(wǎng)站建設(shè)專家,致力于互聯(lián)網(wǎng)品牌建設(shè)與網(wǎng)絡(luò)營(yíng)銷,專業(yè)領(lǐng)域包括網(wǎng)站制作、網(wǎng)站建設(shè)、電商網(wǎng)站制作開發(fā)、微信小程序定制開發(fā)、微信營(yíng)銷、系統(tǒng)平臺(tái)開發(fā),與其他網(wǎng)站設(shè)計(jì)及系統(tǒng)開發(fā)公司不同,我們的整合解決方案結(jié)合了恒基網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗(yàn)和互聯(lián)網(wǎng)整合營(yíng)銷的理念,并將策略和執(zhí)行緊密結(jié)合,且不斷評(píng)估并優(yōu)化我們的方案,為客戶提供全方位的互聯(lián)網(wǎng)品牌整合方案!

一、注冊(cè)輔助類

ClassRegistry:模板函數(shù),用于data、module、contextdata的注冊(cè),其中的函數(shù)解析:

create_object:從RegistryMap里找到傳入name對(duì)應(yīng)的RegistryNode(RegistryNode保存了名字和構(gòu)造函數(shù)),調(diào)用構(gòu)造函數(shù)返回。

register_class:用傳入的name和constructor注冊(cè)RegistryMap,只在Register的構(gòu)造函數(shù)里面調(diào)用,后面會(huì)在ClassRegister<IData> DataRegister、ClassRegister<IModule> ModuleRegister、ClassRegister<IContextData> ContextDataRegister用到。RegistryMap里面的數(shù)據(jù)是從register_class這個(gè)方法插入數(shù)據(jù)進(jìn)去的,后面會(huì)在IMPLEMENT_XXX中調(diào)用到這個(gè)。

fill_name_array:找到RegistryMap里面注冊(cè)的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里面獲取到對(duì)應(yīng)的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,這里會(huì)將輸入的name和構(gòu)造函數(shù)__construct_##name##_data注冊(cè)到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ù)。

在每個(gè)service的cpp文件視線中調(diào)用IMPLEMENT_DATA,注入RegistryMap。

在每個(gè)service的cpp文件的InitInjection中,INJECT_DATA_MODULE_DEPENDENCY把這個(gè)詞典注入到module中。

2.2 module

REGISTER_MODULE:聲明__construct_#name##_module(),返回new module_class;

聲明獲取class的get_##name,函數(shù)體里面返回ModuleMap中保存的對(duì)象(cast_module從ModuleMap里面找到其對(duì)應(yīng)的對(duì)象,如果找不到,則從RegisterMap里面找到其構(gòu)造函數(shù),并調(diào)用create_object之后插入ModuleMap,并返回新建的對(duì)象(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中會(huì)用到的構(gòu)造函數(shù),以及聲明了從ModuleMap中獲取其對(duì)象的get_xxx函數(shù)。

在service的最后調(diào)用IMPLEMENT_MODULE,把module注冊(cè)到RegistryMap中。

2.3 context data

REGISTER_CONTEXT_DATA:聲明__construct_##name##_context_data(),新建data_class;

聲明獲取class的get_##name,函數(shù)體里面通過name查找到ContextDataMap保存的名字簽名對(duì)應(yīng)的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變量,這里會(huì)將輸入的name和構(gòu)造函數(shù)__construct_##name##_context_data注冊(cè)到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:定義一個(gè)把object_ref變量設(shè)置為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這個(gè)對(duì)象的set_##injection_name方法,傳入?yún)?shù)是object_from的引用。結(jié)合DEFINE_INJECTION就是把object_from設(shè)置到object_to這個(gè)對(duì)象里面。

#define INJECT_OBJECT_OBJECT_DEPENDENCY(injection_name, object_from, \
                    object_to)          \
 (object_to).set_##injection_name(&(object_from))

INJECT_MODULE_DEPENDENCY:在上下文context中找到module_from的變量,注入到同一個(gè)上下文的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))

使用:

在上下文相關(guān)的session中調(diào)用INJECT_MODULE_DEPENDENCY、INJECT_DATA_MODULE_DEPENDENCY;

INJECT_MODULE_DEPENDENCY用于把session相關(guān)的信息(比如session_docs、request、response)注入到module中,module的意思是這個(gè)請(qǐng)求需要過的模塊名。

INJECT_DATA_MODULE_DEPENDENCY用于把data注入到module中。

三、總結(jié)

3.1 新增一個(gè)module

在新增module的.h文件最后調(diào)用REGISTER_MODULE聲明了在IMPLEMENT_MODULE中會(huì)用到的構(gòu)造函數(shù),以及聲明了從ModuleMap中獲取其對(duì)象的get_xxx函數(shù)。

在service的最后調(diào)用IMPLEMENT_MODULE,把module注冊(cè)到RegistryMap中。

在上下文相關(guān)的session中調(diào)用INJECT_MODULE_DEPENDENCY、INJECT_DATA_MODULE_DEPENDENCY;

INJECT_MODULE_DEPENDENCY用于把session相關(guān)的信息(比如session_docs、request、response)注入到module中,module的意思是這個(gè)請(qǐng)求需要過的模塊名。

INJECT_DATA_MODULE_DEPENDENCY用于把data注入到module中。

3.2 代碼回顧

ClassRegistry用于給第二項(xiàng)的一堆宏使用。module于類的映射關(guān)鍵在于RegistryMap,新增一個(gè)module的時(shí)候,服務(wù)會(huì)去RegistryMap里面找名字對(duì)應(yīng)的構(gòu)造函數(shù)。RegistryMap里面的數(shù)據(jù)是在IMPLEMENT_MODULE的時(shí)候注入進(jìn)來的name和類的對(duì)應(yīng)關(guān)系。配置文件里面配的是module的鏈條,比如需要過AModule,BModule,這時(shí)候就在init的時(shí)候把所有module都插進(jìn)去,然后在schedule_impl里面調(diào)用每個(gè)module的run函數(shù)。

上述內(nèi)容就是如何在C++中實(shí)現(xiàn)反射,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站muchs.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)站欄目:如何在C++中實(shí)現(xiàn)反射-創(chuàng)新互聯(lián)
轉(zhuǎn)載源于:http://muchs.cn/article28/djihcp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、靜態(tài)網(wǎng)站外貿(mào)建站、面包屑導(dǎo)航、小程序開發(fā)、響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)