C++反射の一種の実現方式
テーマ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を取得
プログラミングを学びたい初心者がいたら、C/C++技術学習ボタンqunに来てください.前は58、93、後ろは4、83-89で、システム全体のC/C++チュートリアルを無料で送ります.IMPLEMENT_DATA:DataRegisterのコンストラクション関数を呼び出します.宣言変数_##name##_module_register、ここで入力したnameと構造関数_construct_##name##_DataはRegistryMapに登録されています.
次の操作を行います.
必要なもの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から来ています).
IMPLEMENT_MODULE:声明_##name##_module_register変数を使用してRegistryMapを挿入します.
次の操作を行います.
新しい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は戻ります.
IMPLEMENT_CONTEXT_DATA:宣言_##name##_context_data変数、ここで入力したnameと構造関数_construct_##name##_context_DataはRegistryMapに登録されています.
2.4 index_data
DECLARE_INDEX_DATA:N for name,VT for VersionIndexタイプ.宣言タイプCはタイプVTで組み立てられ、path、name、descはNで組み立てられるVIAdaptorタイプである.
DEFINE_INDEX_DATA:N for name、ここではstring変数の山を宣言し、dataのpath、name、descに使用します.
2.5 injection
DEFINE_INJECTION:object_を定義するref変数をclass_に設定type*タイプの入力変数の関数です.
INJECT_OBJECT_OBJECT_DEPENDENCY:object_を呼び出すtoこのオブジェクトのset_##injection_nameメソッド、入力パラメータobject_fromの参照.結合DEFINE_INJECTIONはobject_をfromをobject_に設定toこの相手の中に.
INJECT_MODULE_DEPENDENCY:コンテキストcontextでmodule_を見つけますfromの変数、同じコンテキストに注入されたmodule_fromの中.
INJECT_DATA_MODULE_DEPENDENCY:コンテキストcontextで取得したmodule_にdataを注入to中.
INJECT_MODULE_OBJECT_DEPENDENCY:コンテキストcontextで取得したmodule_from注入object_to中.
INJECT_OBJECT_MODULE_DEPENDENCY :object_fromはコンテキストで取得したmodule_に注入されます.to中.
三、まとめ
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に注入するために使用されます.
一、登録補助類
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を取得
#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
プログラミングを学びたい初心者がいたら、C/C++技術学習ボタンqunに来てください.前は58、93、後ろは4、83-89で、システム全体のC/C++チュートリアルを無料で送ります.IMPLEMENT_DATA:DataRegisterのコンストラクション関数を呼び出します.宣言変数_##name##_module_register、ここで入力したnameと構造関数_construct_##name##_DataはRegistryMapに登録されています.
#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から来ています).
#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を挿入します.
#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は戻ります.
#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に登録されています.
#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::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*タイプの入力変数の関数です.
#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この相手の中に.
#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:コンテキストcontextで取得したmodule_にdataを注入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 INJECT_MODULE_DEPENDENCY、INJECT_DATA_MODULE_DEPENDENCY;
INJECT_MODULE_DEPENDENCY session ( session_docs、request、response) 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に注入するために使用されます.