C++反射の実現方法の詳細


一、登録補助類
ClassRegistry:data、module、contextdataの登録に使用されるテンプレート関数.関数の解析:
create_object:RegistryMapから受信nameに対応するRegistryNode(RegistryNodeは名前とコンストラクション関数を保存している)を見つけ、コンストラクション関数を呼び出して返します.
register_class:RegistryMapは、受信したnameとconstructorで登録され、Registerのコンストラクション関数でのみ呼び出され、後でClassRegister Data Register、ClassRegister ModuleRegister、ClassRegister ContextData Registerで使用されます.RegistryMapのデータはregisterからclassこの方法でデータを挿入すると、後にIMPLEMENT_XXXでこれを呼び出します.
fill_name_Array:RegistryMapに登録されているnameを見つけ、入力パラメータを挿入します.
二、使用したマクロ定義
2.1 data
REGISTER_DATA:構築data_の宣言classの関数_construct_##name##_data()が呼び出され、data_が呼び出されます.calssの構造関数;classを取得するget_##を宣言name,関数体のget_data sign_からdata_mapで対応するIDataを取得
?
1 2 3 4 5 6 7 #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(#name); }  \   }                   \   } // wmf::internal
IMPLEMENT_DATA:DataRegisterのコンストラクション関数を呼び出します.宣言変数_##name##_module_register、ここで入力したnameと構造関数_construct_##name##_DataはRegistryMapに登録されています.
?
1 2 3 #define IMPLEMENT_DATA(name)        \   ::wmf::internal::DataRegister __##name##_module_register( \    #name, __construct_##name##_data)
次の操作を行います.
必要なものcppファイルのhファイルの場所呼び出しREGISTER_DATA、コンストラクション関数の宣言とdataのget_の取得xxx関数
各サービスのcppファイル視線でIMPLEMENT_を呼び出すDATA、RegistryMapを注入します.
各サービスのcppファイルのInitInjectionでINJECT_DATA_MODULE_DEPENDENCYはこの辞書をmoduleに注入した.
2.2 module
REGISTER_MODULE:宣言_construct_#name##_module()を返し、new module_を返します.class;
classを取得するget_##を宣言name,関数体の中でModuleMapに保存されているオブジェクトを返します(cast_moduleはModuleMapから対応するオブジェクトを見つけ、見つからない場合はRegisterMapからそのコンストラクション関数を見つけ、create_objectを呼び出してModuleMapを挿入し、新しいオブジェクトを返します(RegisterMapのデータはIMPLEMENT_XXXから来ています).
?
1 2 3 4 5 6 7 8 9 10 11 #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(#name);   \   }              \   }              \   } // wmf::internal
IMPLEMENT_MODULE:声明_##name##_module_register変数を使用してRegistryMapを挿入します.
?
1 2 3 #define IMPLEMENT_MODULE(name)        \   ::wmf::internal::ModuleRegister __##name##_module_register( \    #name, __construct_##name##_module)
次の操作を行います.
新しいmoduleの.hファイル最終呼び出しREGISTER_MODULEはIMPLEMENTでMODULEで使用するコンストラクション関数と、ModuleMapからオブジェクトを取得するget_を宣言します.xxx関数
サービスの最後にIMPLEMENTを呼び出すMODULEは、moduleをRegistryMapに登録します.
2.3 context data
REGISTER_CONTEXT_DATA:宣言_construct_##name##_context_data()、新規data_class;
classを取得するget_##を宣言name,関数体の中からnameでContextDataMapに保存されている名前署名対応のIContextDataを検索してdata_に変換するclassは戻ります.
?
1 2 3 4 5 6 7 8 9 10 11 #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(#name);        \   }                                 \   }                                 \   } // wmf::internal
IMPLEMENT_CONTEXT_DATA:宣言_##name##_context_data変数、ここで入力したnameと構造関数_construct_##name##_context_DataはRegistryMapに登録されています.
?
1 2 3 #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タイプである.
?
1 2 3 4 5 6 7 #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::VIAdaptorvoid (VT)>::type, __index_##N##_path, \               __index_##N##_name, __index_##N##_desc>      \     C
DEFINE_INDEX_DATA:N for name、ここではstring の を し、dataのpath、name、descに します.
?
1 2 3 4 5 6 7 #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*タイプの の です.
?
1 2 #define DEFINE_INJECTION(injection_name, class_type, object_ref) \   void set_##injection_name(class_type* module) { object_ref = module; }
INJECT_OBJECT_OBJECT_DEPENDENCY:object_を び すtoこのオブジェクトのset_##injection_nameメソッド、 パラメータobject_fromの . DEFINE_INJECTIONはobject_をfromをobject_に toこの の に.
?
1 2 3 #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の .
?
1 2 3 4 #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:コンテキストcontextで したmodule_にdataを to .
?
1 2 3 4 #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 .
?
1 2 3 4 #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 .
?
1 2 3 4 #define INJECT_OBJECT_MODULE_DEPENDENCY(injection_point, context, object_from, \                      module_to)               \   ::wmf::internal::get_##module_to(context)->set_##injection_point(      \     &(object_from))
の を います.
コンテキスト セッションでINJECT_を び すMODULE_DEPENDENCY、INJECT_DATA_MODULE_DEPENDENCY;
INJECT_MODULE_DEPENDENCYは、session_docs、request、responseなどのsession をmoduleに するために され、moduleは、このリクエストに なモジュール を する.
INJECT_DATA_MODULE_DEPENDENCYは、dataをmoduleに するために されます.
、まとめ
3.1 moduleを
しいmoduleの.hファイル び しREGISTER_MODULEはIMPLEMENTでMODULEで するコンストラクション と、ModuleMapからオブジェクトを するget_を します.xxx
サービスの にIMPLEMENTを び すMODULEは、moduleをRegistryMapに します.
コンテキスト セッションでINJECT_を び すMODULE_DEPENDENCY、INJECT_DATA_MODULE_DEPENDENCY;
INJECT_MODULE_DEPENDENCYは、session_docs、request、responseなどのsession をmoduleに するために され、moduleは、このリクエストに なモジュール を する.
INJECT_DATA_MODULE_DEPENDENCYは、dataをmoduleに するために されます.
3.2コードレビュー
ClassRegistryは、2 のアイテムのマクロの に されます.moduleのクラスへのマッピングの はRegistryMapにあり、moduleを すると、サービスはRegistryMapの に する を します.RegistryMapのデータはIMPLEMENT_MODULEの に されたnameとクラスの .プロファイルにはmoduleのチェーンが いています. えば、AModule、BModuleを する があります.このとき、initのときにすべてのmoduleを し、schedule_implでは、 moduleのrun が び されます.
この が きか、この があなたに に つと っている は、 りの に することができます.もしあなたがシロであれば、 たちの QQ に することができます:1026095781 1 を け り、 ツール1 を け ります.