c so 反射 C 實現反射機制

2021-10-12 14:11:05 字數 3693 閱讀 1293

.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 ;

#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::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 ;

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

#include

#include // for runtime_error

#endif

template class enumhelper

public:

static const char * tostring(enum_t e)

for(int i = 0; i < _countof(enumhelper::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::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::s_allenums =\

to_enum_item(enum_list)\

template<> const char* enumhelper::s_allenumnames[_countof(enumhelper::s_allenums)];\

template<> char enumhelper::s_singleenumstr = stringize(enum_list) ;\

template<> const char * enumhelper::s_typename = (enumhelper::splitenumdefstring(), #enum_type_name);

c so 反射 c 實現反射機制

下午接了個阿里 面試,當時剛剛睡醒,感覺有點懵。大腦莫名當機狀態,很多問題沒有表述清楚,有乙個關於 c 如何實現反射機制的問題,感覺蠻有意思,當時雖然回答了用函式指標和工廠模式,但是表述並不當,細節也沒有想清楚。晚上抽空簡單實現了一發 file name reflector.cpp author x...

c so 反射 C 反射的方法與實現

1.什麼是反射?反射是程式獲取自身資訊的能力 2.反射有什麼用?可以用於動態建立型別,跨語言跨平台資料互動,持久化,序列化等等。3.反射包含哪些功能?至少包含以下功能 列舉所有member 獲取member的name和type 能夠get set member 4.有哪些反射方法?反射主要有3種實現...

c 實現反射機制

c 中反射機制比較常見,而c 中沒有該機制。使用c 實現反射機制,主要利用了工廠模式程序物件的生產。itest.h 基類test.h 繼承類helper.h 幫助類main.cpp 主函式入口檔案 pragma once include using namespace std class itest...