亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于C++的反射框架研究與實現(xiàn)

        2021-11-05 08:04:04楊樹仁張啟明孫為康王鴻顯
        電子技術與軟件工程 2021年17期
        關鍵詞:基類枚舉對象

        楊樹仁 張啟明 孫為康 王鴻顯

        (中船航??萍加邢挢熑喂?北京市 100071)

        1 引言

        目前,Java、C#等編程語言具有較為成熟的反射框架,在實踐中受到了廣泛應用。但是,C++語言本身并不支持這一動態(tài)特性。雖然,在C++新標準中增加了許多類型信息提取方式,增強了模板元編程能力,但是整體上還不是一套完整的反射框架。目前已有許多不同實現(xiàn)機理的C++反射框架,如QT、UE4 等,但是與高級語言相比仍存在較大的差距,具有一定的局限性。

        因此,本文主要研究目的是基于C++語言建立一個結構簡單、功能完備、性能高效的通用型反射框架,盡量涵蓋高級編程語言的所有反射功能,為C++反射框架的標準化建設提供理論指導。

        2 概述

        元數(shù)據(jù)是描述數(shù)據(jù)的數(shù)據(jù),類型元數(shù)據(jù)用于描述類型定義信息[2]。本文中將類型定義信息稱為類型特征信息,將加工處理后的類型特征信息稱為類型元數(shù)據(jù)。反射框架的主要任務是提取類型特征信息,存入元數(shù)據(jù)倉庫,再通過對元數(shù)據(jù)的合理使用實現(xiàn)反射功能。

        本文設計的反射框架主要包括特征信息提取、類型注冊、元數(shù)據(jù)應用、對象系統(tǒng)四部分。特征信息提取和類型注冊是反射框架的基礎,元數(shù)據(jù)應用和對象系統(tǒng)是反射框架的成果,只有提取到更加豐富的類型特征,才能建立功能完備的反射框架。

        3 特征信息提取

        特征信息包括基礎信息、函數(shù)信息、屬性信息、注解信息、枚舉信息、基類信息等,以模板元編程作為主要提取手段,在程序編譯階段提取特征信息,提高運行期效率。

        3.1 基礎信息

        基礎信息主要描述類型自身固有信息,如名稱、內(nèi)存大小、類別(枚舉、指針、函數(shù)、容器)、特征(指針特征、裝箱特征、元素特征)等。下面對幾種信息進行重點介紹:

        3.1.1 類型名稱

        本文基于內(nèi)置宏(__FUNCSIG__或__PRETTY_FUNCTION__)提取類型名稱,利用模板函數(shù)特化方式返回包含類型名稱的字符串,然后在類型注冊階段加工提取,得到標準化類型名稱。

        3.1.2 指針特征

        指針特征包括指針間址級數(shù)與一級指針信息。一級指針類型是間址級數(shù)為1 的指針類型,可以在無完整類型定義的情況下獲取類型信息,適合作為多級指針的銜接點。

        3.1.3 裝箱特征

        裝箱是對象通用化的一種手段,是將對象存入通用對象(俗稱:箱子)的過程。裝箱特征,也稱為裝箱模式,用于描述對象在箱子內(nèi)部的存儲模式,分為值模式和共享模式。一般值模式對象存儲于棧區(qū),拷貝過程按值傳遞。共享模式對象存儲于堆區(qū),拷貝過程按引入傳遞。

        3.1.4 容器類型

        容器類型主要指STL 容器類型或滿足容器判據(jù)的類型,如vector、list、map、QList 等。容器判據(jù)是判斷類內(nèi)是否定義const_iterator 與value_type 類型或別名。

        3.1.5 元素特征

        主要包括容器元素和模板元素兩種特征。容器元素指容器內(nèi)部存儲類型,如map的元素類型為pair。模板元素類型,指模板參數(shù)類型,如pair的元素類型為T1 和T2。

        元素特征信息提取主要采用分支模板的方式,針對不同類型獲取相應的元素類型信息,也可以通過模板特化或偏特化的方式創(chuàng)建自定義的分支模板。

        3.2 函數(shù)信息

        類成員函數(shù)包括普通函數(shù)、靜態(tài)函數(shù)和特殊函數(shù)(默認構造函數(shù)、拷貝構造函數(shù)、拷貝賦值函數(shù)、析構函數(shù)、垃圾回收函數(shù)、運算符重載函數(shù)、元數(shù)據(jù)取值函數(shù)、字符串序列化函數(shù)、哈希碼取值函數(shù)、容器讀寫函數(shù)等)。

        工廠模板的無參特化類型可自動區(qū)分不同函數(shù)類型,簡化函數(shù)代理創(chuàng)建過程。工廠模板的有參偏特化類型可自動區(qū)分同名重載函數(shù)。最終,函數(shù)信息存儲于函數(shù)代理中,以抽象類FunctionProxy作為顯示調(diào)用接口。

        特殊函數(shù)信息提取過程主要依靠編譯器SFINAE 特性自動判定是否存在指定函數(shù),然后利用代理函數(shù)提取函數(shù)信息。下面對幾種特殊函數(shù)進行介紹:

        3.2.1 構造函數(shù)

        對象構造工廠模板是實現(xiàn)對象通用構造一種方法,通過引入代理函數(shù)解決了無法獲取構造函數(shù)指針的問題,可以適用于任何類型對象的構造過程。在應用對象構造工廠前,先利用SFINAE 特性進行條件判定,僅條件成立才注冊構造函數(shù)信息。對于平凡類型來說,由于構造規(guī)則比較簡單,不必引入代理函數(shù)輔助。

        3.2.2 垃圾回收函數(shù)

        主要服務于內(nèi)存管理的垃圾回收過程(GC)。當GC 過程判定對象不可達時,會自動執(zhí)行對象的垃圾回收函數(shù),提前通知對象,便于開發(fā)者主動釋放相關資源。利用SFINAE 特性,當且僅當類存在垃圾回收函數(shù)時,才提取回收函數(shù)信息,模板判據(jù)是decltype(std::declval().Dispose())。

        3.2.3 元數(shù)據(jù)取值函數(shù)

        是類的虛函數(shù)成員,主要利用虛函數(shù)動態(tài)聯(lián)編特性,運行階段會動態(tài)選擇合適的取值函數(shù)返回正確的類型元數(shù)據(jù)和實際的對象指針,有效地實現(xiàn)接口(或指針)轉(zhuǎn)換。

        3.3 屬性信息

        屬性是面向?qū)ο缶幊痰闹匾拍?,用于表示對象的性質(zhì)和關系。在編程語言中,屬性通常具有三個要素:屬性名、get 訪問器、set訪問器。成員變量是自帶屬性名和讀寫訪問器的特殊屬性。

        3.3.1 成員變量信息

        成員變量特征信息主要包括變量名、類型、偏移地址、靜態(tài)特征。其中,變量名通過宏定義參數(shù)字符化方式獲取,變量類型通過decltype 進行反向推導獲取,靜態(tài)特征通過模板is_member_object_pointer 進行判定,偏移地址通過表達式addressof(((T*)0)->name)獲取。

        3.3.2 屬性信息提取

        主要包括屬性名、類型、set 訪問器、get 訪問器。通過宏定義的方式主動設定屬性名與屬性類型。set 訪問器和get 訪問器的獲取方式與類成員函數(shù)信息獲取方式相同。附加了靜態(tài)檢查功能,當訪問器類型與屬性類型不一致時,提示編譯錯誤信息。

        3.4 注解信息

        注解是一種支持反射的信息標注,是一種更高級的代碼注釋,是對類型、屬性、函數(shù)、枚舉值等定義信息的補充說明。本文的注解與Java 注解概念一致,也等同于C#的特性。

        從編程實現(xiàn)角度出發(fā),注解信息是一種特殊對象,也包括對象類型和對象地址信息,將注解信息附加到指定類型的元數(shù)據(jù)內(nèi),就成為了這個類型特有信息,也稱為類型特性。

        3.5 枚舉信息

        枚舉信息主要用于枚舉值和枚舉名的動態(tài)轉(zhuǎn)換功能。QT 框架提供了Q_ENUMS 簡化了枚舉信息的提取過程,但是僅適用于具有Q_OBJECT 或Q_GADGET 聲明的類內(nèi)枚舉類型,適用范圍有限。

        本文利用可變宏定義的方式,設計了一種更加簡單有效的枚舉信息提取方法,彌補了QT 無法提取類外枚舉信息的不足。部分宏定義如下:

        其中,DECL_ENUM 用于類內(nèi)枚舉類型的定義,DECL_ENUM_NS 用于類外枚舉類型的定義。將InitHelper 與ValueHelper結合實現(xiàn)了自動提取枚舉值列表功能,前者判定枚舉值是否存在等號賦值,后者實現(xiàn)枚舉值遞增判定,利用函數(shù)ParseEnumTable 建立枚舉值與枚舉名的映射關系。

        3.6 基類信息

        基類信息用于描述類的繼承關系,包括基類類型與地址偏移。由于基類類型無法通過類型推導、內(nèi)置宏、模板元編程等方式自動提取,因此本文主要用宏定義方式實現(xiàn)基類注冊,包括侵入式和非侵入式兩種注冊方式。地址偏移是子類與基類對象間的內(nèi)存地址偏移,主要用于接口變換,可以通過表達式(int)(intptr_t)(static_cast((T*)1))-1 進行計算。

        4 類型注冊

        類型注冊是以元數(shù)據(jù)模型為基礎,將特征信息加工處理生成元數(shù)據(jù),再存入元數(shù)據(jù)倉庫的過程。

        4.1 元數(shù)據(jù)模型

        元數(shù)據(jù)模型不僅是類型注冊的基礎,也是整個反射框架的基礎。元數(shù)據(jù)以MetaData 作為基類,存儲注解信息,并派生了類型元數(shù)據(jù)、屬性元數(shù)據(jù)、函數(shù)元數(shù)據(jù)。類型元數(shù)據(jù)用于存儲公用的類型信息,派生了指針類型元數(shù)據(jù)、類元數(shù)據(jù)、枚舉類型元數(shù)據(jù)、函數(shù)類型元數(shù)據(jù),分別存儲各自的特征信息。注意區(qū)分函數(shù)類型元數(shù)據(jù)與函數(shù)元數(shù)據(jù),前者主要存儲函數(shù)類型的定義信息,后者主要存儲代理函數(shù)信息。注意區(qū)分類型元數(shù)據(jù)與類元數(shù)據(jù),前者為基類,后者僅存儲class 或struct 類型的特征信息。

        4.2 注冊宏

        類型注冊的核心是MetaRegister,表現(xiàn)形式是注冊宏。注冊宏是簡化類型注冊的有效手段,輔助開發(fā)者快速完成類型反射部分代碼的編寫。

        (1)類型注冊宏:表達式為REG_TYPE(Type){…},其中類內(nèi)的函數(shù)、屬性、枚舉、注解等信息注冊均在大括號內(nèi)完成。程序執(zhí)行階段的類型注冊過程均會在main 函數(shù)前完成。

        (2)函數(shù)注冊宏:表達式為REG_FUNCTION(Name)或REG_FUNCTION(Name,Define),后者主要用于注冊重載函數(shù)。

        (3)構造注冊宏:用于注冊構造函數(shù),表達式為REG_CTOR(ArgTypes),其中ArgTypes 表示形參類型。

        (4)屬性注冊宏:表達式為 REG_PROPERTY(Name) 或REG_PROPERTY(Name,Type,[[Getter],[Setter]]),前者用于注冊成員變量信息,后者的Getter 和Setter 表示可選的訪問器函數(shù)名,可按需添加相應的訪問器。

        (5)注解注冊宏:基本形式為ANNOTATION(Type(Args),[Fi eld=Value])。如果附加在類型注冊宏后,表示為類型添加注解;附加在函數(shù)注冊宏后,表示為函數(shù)添加注解;附加在屬性注冊宏后,表示為屬性添加注解。

        (6)枚舉注冊宏:表達式為DECL_ENUM(Type,Values)或DECL_ENUM_NS(Type,Values),前者用于定于類內(nèi)枚舉類型,后者用于定義類外枚舉類型。

        (7)基類注冊宏:表達式為REG_BASE(Type,Bases)或REG_BASE_NS(Type,Bases),前者屬于侵入式,后者屬于非侵入式,表達的意思相同。

        4.3 合法性檢查

        合法性檢查是在程序運行期檢查類型信息合法性,與編譯階段靜態(tài)斷言相結合,能夠有效避免人為錯誤。

        5 元數(shù)據(jù)應用

        如圖7所示,元數(shù)據(jù)模型對外提供了四個基礎類型:MetaType、MetaProperty、MetaFunction 和MetaAnnotation,分別應用類型信息、屬性信息、函數(shù)信息以及注解信息實現(xiàn)動態(tài)反射功能。其中MetaType 主要實現(xiàn)類型檢索、動態(tài)構造、成員檢索、基類檢索、萬能轉(zhuǎn)換等功能;MetaProperty 主要實現(xiàn)屬性動態(tài)讀寫功能;MetaFunction 主要實現(xiàn)函數(shù)動態(tài)調(diào)用功能;MetaAnnotation 主要實現(xiàn)注解信息動態(tài)讀取功能。

        6 對象系統(tǒng)

        對象系統(tǒng)主要提供數(shù)據(jù)通用化封裝方法,表現(xiàn)為對象裝箱和拆箱操作。裝箱是將對象封裝為通用對象的過程。拆箱是將通用對象轉(zhuǎn)換成指定類型對象或接口的過程。反射框架的重要應用成果,就是實現(xiàn)對通用對象的構建、傳遞、屬性讀寫、函數(shù)調(diào)用等功能。

        共享模式主要基于共享智能指針的思想實現(xiàn)的,通過引用計數(shù)器表示對象的使用情況,在計數(shù)器為0 時自動釋放共享內(nèi)存。然而,這種方式不可避免的會進入智能指針的依賴陷阱,即閉環(huán)引用問題。為了解決這個問題,本文引入了垃圾回收機制,主要基于標記清除算法,將不可達對象執(zhí)行自動回收,可以有效回收閉環(huán)孤島,同時采用分代回收策略提高垃圾回收效率。

        7 結束語

        本文基于C++語言設計了一個結構簡單、性能高效、功能完備的通用版反射框架,具有特征信息提取、類型注冊、元數(shù)據(jù)應用和對象系統(tǒng)四大主要模塊,設計了有效的元數(shù)據(jù)模型以及對象系統(tǒng)模型,實現(xiàn)了萬能轉(zhuǎn)換、動態(tài)構造、動態(tài)屬性讀寫、動態(tài)函數(shù)調(diào)用、注解反射、裝箱拆箱、垃圾回收等高級功能,幾乎涵蓋了高級語言的所有反射特性。本文設計的反射框架要求編譯器至少支持C++11標準,經(jīng)測試,能夠在GCC4.8.1 下正常編譯運行。

        猜你喜歡
        基類枚舉對象
        神秘來電
        睿士(2023年2期)2023-03-02 02:01:09
        基于理解性教學的信息技術教學案例研究
        速讀·上旬(2022年2期)2022-04-10 16:42:14
        基于C#面向?qū)ο蟪绦蛟O計的封裝、繼承和多態(tài)分析
        一種高效的概率圖上Top-K極大團枚舉算法
        攻略對象的心思好難猜
        意林(2018年3期)2018-03-02 15:17:24
        基于熵的快速掃描法的FNEA初始對象的生成方法
        空戰(zhàn)游戲設計實例
        基于太陽影子定位枚舉法模型的研究
        區(qū)間對象族的可鎮(zhèn)定性分析
        一種基于用戶興趣的STC改進算法
        服裝學報(2015年1期)2015-10-21 01:20:30
        久久久久亚洲av片无码下载蜜桃 | 欧美人与动牲交片免费| 欧美综合区自拍亚洲综合| 国产成人高清视频在线观看免费 | 欧美性猛交xxxx乱大交极品| 大桥未久亚洲无av码在线| 欧美一级特黄AAAAAA片在线看| 国产精品视频免费一区二区三区 | 免费大片黄在线观看| 亚洲AV秘 片一区二区三区 | 131美女爱做视频| 91精品国产91久久综合桃花| 国产亚洲专区一区二区| 亚洲av国产av综合av卡| 亚洲一区二区观看播放| 亚洲日韩AV无码美腿丝袜| 日本视频在线观看一区二区| 国产欧美日韩一区二区三区| 日本五月天婷久久网站| 亚洲国产精一区二区三区性色| 东北女人一级内射黄片| 国产97在线 | 亚洲| 亚洲国产精品久久久天堂不卡海量| 亚洲精品乱码久久麻豆| 伊人久久大香线蕉av波多野结衣| 狠狠色综合网站久久久久久久| 国产精品无码久久久久久蜜臀AV | 亚洲一道一本快点视频| 中文乱码字字幕在线国语| 亚洲精品乱码久久久久久蜜桃不卡| 婷婷色综合成人成人网小说| 永久免费看黄网站性色| 少妇精品无码一区二区三区| 国产欧美日产久久| 日本大片在线一区二区三区| 亚洲中文字幕日产无码| 亚洲精品久久无码av片软件| 日本一区二区国产高清在线播放| 中文字幕漂亮人妻在线| 日本不卡一区二区三区在线| 欧美v日韩v亚洲综合国产高清|