1. 什麼是反射?
反射是程式獲取自身資訊的能力
2. 反射有什麼用?
可以用於動態建立型別,跨語言跨平台資料互動,持久化,序列化等等。
3. 反射包含哪些功能?
至少包含以下功能:列舉所有member
獲取member的name和type
能夠get/set member
4. 有哪些反射方法?
反射主要有3種實現方法結構化語言
比如xml/json/yml/protobuf等語言,或者dicom,tiff等資料格式,在標準裡規範了如何獲取欄位的方法。
執行期反射
大多數語言都支援執行期反射,比如.net系列,js, python, perl, matlab等。
編譯期反射
目前只發現d語言有這個功能。c++用巨集也能實現
5. c++反射有哪些方法?
5.1 編譯器支援c++20據說有編譯期反射,但那是可能是n年後的事情了。
msvc的clr擴充套件支援執行期反射,但clr不算標準c++。
clang的智慧型補全外掛程式,修改一下能輸出結構體資訊,可以做個工具,但這只適合clang。
5.2 執行期支援
各種debugger都能取得結構體資訊的,可以利用。有些編譯器在realse的時候,不輸出符號,需要設定realse輸出符號表才行。優點是用起來簡單,缺點是跨平台不太好,網上能搜到一些**,輪子哥 @vczh 曾經貼過實現。lldb提供了很好的介面,而且支援python
dbghelp.dll有乙個不太好介面
gdb也可以,有python介面
5.3 第三方工具
既然c++沒有原生支援反射,那麼用第三方工具,生成特殊的c++**,自帶反射也是乙個辦法。常見的有:json schemaxml attributeproto-buf
5.4 macro (巨集)
以上種種,基本都需要c++語言之外的辦法,而巨集是語言本身支援的。巨集的實現主要有兩類:侵入式
即在類內部,使用巨集標記成員,好處是可以同步更改,不足是需要標頭檔案可編輯。非侵入式
即在類外部,使用巨集標記成員,好處是不需要改動原始宣告,不足是修改不同步。
6. c++用巨集實現反射示例
實際使用中,往往是同時使用侵入式和非侵入式的。對於外部庫,比如stl用非侵入式,對於自己定義的型別用侵入式,無論哪種辦法,最後都要需要形成類似這樣的輔助類:
各種實現,有的用宣告了輔助類,有的用了friend函式,用的用了static函式,等等不一而足,不在一一枚舉,實際上並沒有什麼本質差異。
6.1 非侵入式實現
關鍵在於nms_cpp_for這個巨集迴圈上,c99的變參,在不同編譯器上是不一樣的,實現起來很墨跡,這裡不就深究變參巨集了。boost_cpp裡面有原始碼,有興趣的可以研讀(我的github也有一種實現)。
6.2 侵入式實現
侵入式實現可以不需要這個額外helper型別,直接用原來的型別即可。巨集展開如下:
關鍵在於uid的序號如何獲取,c++編譯器一般提供了內建巨集__counter__,做為遞增數。但是這個巨集不能重新置0, 所以,上面的**實際上,是不能實現的,需要改為如下:
7. 示例**
執行後輸出:
參考實現
c so 反射 C 實現反射機制
net下的很多技術都是基於反射機制來實現的,反射讓.net平台下的語言變得得心應手。最簡單的,比如列舉型別,我們我可以很容易的獲得乙個列舉變數的數值以及其名稱字串。可是,在c 中,列舉變數本質上和乙個整形變數沒有區別,我們很難獲取乙個列舉變數的名稱字串。其實在c 中,我們可以通過巨集來實現類似反射的...
c so 反射 c 實現反射機制
下午接了個阿里 面試,當時剛剛睡醒,感覺有點懵。大腦莫名當機狀態,很多問題沒有表述清楚,有乙個關於 c 如何實現反射機制的問題,感覺蠻有意思,當時雖然回答了用函式指標和工廠模式,但是表述並不當,細節也沒有想清楚。晚上抽空簡單實現了一發 file name reflector.cpp author x...
反射 方法的反射04
方法的反射 1.如何獲取某個方法 方法的名稱和方法的引數列表才能唯一的決定某個方法 2.方法反射的操作 method.invoke 1.要獲取乙個方法就是獲取類的資訊,獲取類的資訊首先獲取類的類型別 student s new student class c s.getclass 2.獲取方法,由名...