C++实现反射机制(一)
来源:互联网 发布:人工智能分析用户行为 编辑:程序博客网 时间:2024/05/16 03:00
NET下的很多技术都是基于反射机制来实现的,反射让.NET平台下的语言变得得心应手。最简单的,比如枚举类型,我们我可以很容易的获得一个枚举变量的数值以及其名称字符串。
可是,在C++中,枚举变量本质上和一个整形变量没有区别,我们很难获取一个枚举变量的名称字符串。
其实在C++中,我们可以通过宏来实现类似反射的机制。
接下来,我想总结一下如何在C++中实现一个类似于C#枚举类型的方法。
- __VA_ARGS__
- 使用__VA_ARGS__,我们可以定义带可变参数的宏,举个例子:
- #define MY_PRINTF(…) printf(__VA_ARGS__)
- 这样我们写
- MY_PRINTF("hello, %s”, "world");
- 就等价于
- printf("hello, %s”, "world");
宏的"##"符号
"##"符号的作用是在可变参数的个数为0时,消除参数前面的逗号:
#define MY_PRINTF(fs, …) printf(fs, ##__VA_ARGS__)
我们这样调用:
MY_PRINTF(“Hello, World”);
等价于
printf(“Hello, World”);
另外"##"符号还能够去掉括号,但是我现在还不是很明白,为什么能够做到这一点:
- #define ENUM_COTENTS(...) __VA_ARGS__
- #define ENUM_CONTENT_REMOVE_PARENTHESIS(a) ENUM_COTENTS##a
- #define DEFINE_ENUM(name) enum name { ENUM_CONTENT_REMOVE_PARENTHESIS(ENUM_LIST) };
- #define ENUM_LIST (Sunday=1,Monday=2)
- DEFINE_ENUM(WeekDay)
宏的"#"符号
"#"符号的作用是“字符化”代码:
#define MY_STRINGLIZED_MACRO(str) #str
int helloWorld = 0;
printf(MY_STRINGLIZED_MACRO(helloWorld)); // output: helloWorld
利用C++宏实现简单的.NET枚举类型
我做了一个简单的用例,最终示例代码如下:
- #include "DefineEnum.h"
- #define ENUM_LIST \
- ENUM_NAME(Sunday ENUM_VALUE(10)), \
- ENUM_NAME(Monday ENUM_VALUE(Sunday+1)), \
- ENUM_NAME(Tuesday ENUM_VALUE(123)), \
- ENUM_NAME(Wednesday ENUM_VALUE(10)) , \
- ENUM_NAME(Thursday ENUM_VALUE(7)), \
- ENUM_NAME(Friday ENUM_VALUE(8)), \
- ENUM_NAME(Saturday ENUM_VALUE(12))
- DEFINE_ENUM(WeekDay);
- #include "RegisterEnum.h"
- REGISTER_ENUM(WeekDay);
- int main()
- {
- printf("%s is %d.", EnumHelper<WeekDay>::ToString(Monday), Monday);
- getchar();
- return 0;
- }
DefineEnum.h
- #undef ENUM_LIST
- #undef ENUM_NAME
- #define ENUM_NAME(...) __VA_ARGS__
- #undef ENUM_VALUE
- #define ENUM_VALUE(val) = val
- #define ENUM_COTENTS(...) __VA_ARGS__
- #define DEFINE_ENUM(name) enum name { ENUM_COTENTS(ENUM_LIST) };
RegisterEnum.h
- #include "ReflectEnum.h"
- #undef ENUM_VALUE
- #define ENUM_VALUE(val)
- #define REGISTER_ENUM(name) REFLECT_ENUM(name, ENUM_LIST )
ReflectEnum.h
- #ifndef REFLECT_ENUM_INCLUDE_GUARD
- #include <string>
- #include <cstring>
- #include <stdexcept> // for runtime_error
- #endif
- template <typename Enum_T> class EnumHelper
- {
- public:
- static const char * ToString(Enum_T e)
- {
- for(int i = 0; i < _countof(EnumHelper<Enum_T>::s_allEnums); i++)
- {
- if( s_allEnums[i] == e)
- return s_allEnumNames[i];
- }
- return NULL;
- }
- private:
- static const char * s_typeName;
- static Enum_T s_allEnums[];
- static char s_singleEnumStr[];
- static const char * s_allEnumNames[];
- static void SplitEnumDefString()
- {
- char * p = s_singleEnumStr;
- while( isspace(*p) ) p++;
- for(int i = 0; i < _countof(EnumHelper<Enum_T>::s_allEnums); i++)
- {
- s_allEnumNames[i] = p;
- while( *p == '_' || isdigit(*p) || isalpha(*p) ) p++;
- bool meet_comma = ( *p == ',' );
- *p++ = '\0';
- if( !meet_comma )
- {
- while( *p && *p != ',') p++;
- if( *p ) p++;
- }
- while( *p && isspace(*p) ) p++;
- }
- }
- };
- #define TO_ENUM_ITEM(...) __VA_ARGS__
- #define STRINGIZE(...) #__VA_ARGS__
- #define REFLECT_ENUM(enum_type_name, enum_list) \
- template<> enum_type_name EnumHelper<enum_type_name>::s_allEnums[] = \
- { \
- TO_ENUM_ITEM(enum_list) \
- }; \
- template<> const char* EnumHelper<enum_type_name>::s_allEnumNames[_countof(EnumHelper<enum_type_name>::s_allEnums)]; \
- template<> char EnumHelper<enum_type_name>::s_singleEnumStr[] = STRINGIZE(enum_list) ; \
- template<> const char * EnumHelper<enum_type_name>::s_typeName = (EnumHelper<enum_type_name>::SplitEnumDefString(), #enum_type_name);
0 0
- C++实现反射机制(一)
- C++实现反射机制(一)
- java反射机制的实现原理 (一)
- 通过反射机制实现加一操作
- c 结构体反射机制实现
- Java反射机制(一)
- Java反射机制一
- java反射机制 一
- OC反射机制一
- JAVA反射机制(一)
- 反射机制一
- 反射机制(一)
- Java反射机制(一)
- 反射机制(一)
- 浅谈反射机制(一)
- 反射机制(一)
- java反射机制(一)
- 利用Objective-C的反射机制和运行时特性实现类静态方法的动态访问(一)
- hdu 1558
- printf "%.*s"
- LiveCMN API
- Android应用层View绘制流程与源码分析
- akoj-1055-矩阵乘法
- C++实现反射机制(一)
- 排版公式的多行下标
- 常用开源Jabber(XMPP) IM服务器介绍
- C++实现反射机制(二)
- Android Bitmap回收 注意事项
- Android应用AsyncTask处理机制详解及源码分析
- 路由器安全测试工具 – Router Scan v2.51
- 为程序界面添加滑动条--createTrackbar()
- 重新教自己学算法之图的遍历(十一)—深度(DFS)和广度(BFS)