欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++ 完備的運(yùn)行時(shí)類型信息(動(dòng)態(tài)類型信息)

 更新時(shí)間:2017年07月23日 16:05:39   作者:huaxiazhihuo  
這篇文章主要介紹了c++ 完備的運(yùn)行時(shí)類型信息,需要的朋友可以參考下

眾所周知,碼猿寫代碼,自然要求嚴(yán)謹(jǐn)周密,殊不知想象力也很重要。本座閱碼幾十年,很是感概很多碼猿的腦洞被大大禁錮,鮮有人能越雷池一步,特別是c++的同學(xué),連同委員會的那一坨老頭子,都很讓人無語至極,出自這些人的作品,都是一個(gè)死魚眼睛樣子,千人一面,毫無靈動(dòng)之生趣可言。stl,boost這些庫都是這樣子(雖然它們確實(shí)可以完成大多數(shù)日常任務(wù)),更別說其他的庫,沒有什么讓人耳目一新之處。

就說說動(dòng)態(tài)類型信息這塊,又或者說是反射。自然,語言本身提供的廢物type_info就懶得說了,除了證明c++也東施效顰,也能支持動(dòng)態(tài)信息之外,就別無用處了,有誰會正兒八經(jīng)的用type_info做點(diǎn)正兒八經(jīng)的事情呢。因此,各路人馬紛紛上陣,都要彌補(bǔ)c++在運(yùn)行時(shí)類型信息上的缺失。因?yàn)轭愋偷姆瓷湫畔?shí)在太重要,或者說,反射的用武之地太多太多,表面上很多事情不需要反射,或者字面代碼上就看不到反射的痕跡,但是內(nèi)里的實(shí)現(xiàn),大把大把的反射在發(fā)光發(fā)熱。c++堅(jiān)持不在動(dòng)態(tài)信息上給予一點(diǎn)點(diǎn)多余的支持,并不表示c++就不需要反射了,看看標(biāo)準(zhǔn)庫這個(gè)極力回避動(dòng)多態(tài)的典范,是一個(gè)怎樣的失敗作品,嗯,這個(gè)以后再談吧。假如stl一開始就沒有如此大力排斥動(dòng)多態(tài),你看看就連內(nèi)存分配的allocator都可以做到靜態(tài)類型信息里面(最新版的c++終于也要接受多態(tài)的allocator,c++界居然一片歡呼鼓舞,真是悲哀),今時(shí)今日的c++就不會在很多領(lǐng)域上到處割地求和。

總的來說,現(xiàn)在市面上的c++反射庫,都是侵入式,都學(xué)著mfc那一套,都是要求繼承自一個(gè)基類Object,然后才能對外提供反射信息的功能,先不說它們提供的類型信息是否完備,這樣子就把用途廣泛限制死在一個(gè)很窄很窄的小圈子里面了。這些反射庫,1、不能反射基本類型,int、char、double、const char*、……等;2、不能反射非繼承自O(shè)bject的class或者struct,3、也不能反射模板類,比如vector<int>、list<vector<vector<int>>>。雖然typeid千般弱雞,但也非一無是處,起碼非侵入、平等、多態(tài)。所以,理想的反射,應(yīng)該像c++原生的typeid那樣無色無味:1、非侵入式的;2、可以對所有的類型都提供反射,基本類型、非Object系的struct或者class、template類型的;3、多態(tài)的,只要改類型需要運(yùn)行時(shí)的類型識別,那么就返回其本身的類型(子類),而非字面上的聲明類型;4、支持類型參數(shù),也即是說,以類型傳遞給該函數(shù)時(shí),就返回相應(yīng)的類型信息對象。

說得具體一點(diǎn),我們要求的反射庫是這樣子的。當(dāng)然,首先要有一個(gè)類型信息對象TypeInfo,里面裝滿了關(guān)于對于類型的所有詳細(xì)信息。如下所示:可以猜到這種反射下框架,只支持單繼承,這是故意的。

struct TypeInfo
 {
 public:
  template<typename Args>
  void ConstructObject(void* obj, MemoryAllocator* alloc, Args&& args)const;
  bool IsDerviedOf(const TypeInfo* base)const;

 public:
  virtual TIType GetTIType()const = 0;
  virtual const InterfaceMap* GetInterfaces()const;
  virtual jushort GetMemorySize()const;
  virtual ConstText GetName() const;
  virtual AString GetFullName()const;
  virtual jushort GetAlignSize() const;
  virtual ConstText GetSpaceName()const;
  virtual const TypeInfo* GetBaseTypeTI()const;
  virtual const TypeInfo* GetPointeedTI()const;
  virtual size_t GetHashCode(const void* obj)const;
  virtual bool IsValueType()const { return true; }
  virtual bool IsClass()const { return true; }

  virtual bool DoInitAllocator(void* obj, MemoryAllocator* memAlloc)const;
  virtual bool NeedDestruct()const { return false; }
  virtual void DoDefaultConstruct(void* obj)const;
  virtual bool CanDefaultConstruct()const { return true; }
  virtual void DoAssign(void* dest, const void* src)const;
  virtual bool Equals(const void* objA, const void* objB)const;
  virtual void DoDestruct(void* obj)const;
  
 };

然后,就要有一個(gè)函數(shù)TypeOf,應(yīng)該是兩個(gè),一個(gè)是無參數(shù)的類型模板函數(shù),可以這樣調(diào)用,TypeOf<type>();一個(gè)是有一個(gè)參數(shù)的類型模板函數(shù),可以這樣調(diào)用,TypeOf(obj)。不管是那一個(gè),其返回結(jié)果都是const TypeInfo*。TypeOf的要做到的事情是,對于每一種類型,有且只有一個(gè)唯一的TypeInfo對象與之對應(yīng),不管是template的還是非template的;比如,以下的幾個(gè)判斷必須成立。
TypeOf<int>() == TypeOf<int>();
TypeOf<int>() == TypeOf(n); //n為整型
TypeOf<vector<int>>() == TypeOf(nums);//nums的類型為vector<int>
Object* a = new ObjectA; TypeOf(a) == TypeOf<ObjectA>();
其實(shí)這里面的原理也沒什么神奇,無非就是trait配合sfine,接下來就全部都是苦力活,就是為每一種類型都專門特化一個(gè)詳細(xì)描述的類型對象,用宏可以節(jié)省大量的代碼。但是整個(gè)反射庫,本座前前后后重構(gòu)了十幾次,現(xiàn)在也還在重構(gòu)之中,終究還是解決了開發(fā)上所遇到的各種事情。比如,序列化(支持指針、支持多態(tài))、對象與xml的互換、對象與json的互換、數(shù)據(jù)庫表讀寫對象、格式化、Any類型、非侵入式接口、消息發(fā)送、字符串生成對象等等。
其實(shí)現(xiàn)方式,概括起來,就是引入間接層元函數(shù)TypeInfoImp專門用于返回一個(gè)類型type,type里面有一個(gè)GetTypeInfo()的函數(shù)。然后TypeOf調(diào)用TypeInfoImp里的type的GetTypeInfo()最終得到TypeInfo對象。代碼如下所示。

template<typename Ty> struct TypeInfoImp
 {
  typedef Ty type;
  static const bool value = THasGetTypeInfoMethod<Ty>::value;
 };

 template<typename Ty>
 struct TypeInfoImp<const Ty> : public TypeInfoImp<Ty>
 {
  typedef typename TypeInfoImp<Ty>::type type;
  static const bool value = TypeInfoImp<Ty>::value;
 };
 
 template<typename Ty>
 const TypeInfo* TypeOf()
 {
  typedef typename TypeInfoImp<Ty>::type TypeInfoProvider;
  return TypeInfoProvider::GetTypeInfo();
 }
 
 template<typename Ty>
 const TypeInfo* TypeOf(const Ty& obj)
 {
  typedef typename IsRttiType<Ty>::type is_rtti; //又是間接層,對動(dòng)態(tài)類型和非動(dòng)態(tài)類型分別處理
  return ImpTypeOf(obj, is_rtti());
 }
 
 template<>
 struct TypeInfoImp < bool >
 {
  static const bool value = true;
  typedef TypeInfoImp<bool> type;
  static TypeInfo* GetTypeInfo();
 };
  
 TypeInfo* TypeInfoImp<bool>::GetTypeInfo()
 {
  static TypeInfo* ti = CreateNativeTypeInfo<bool>("bool");
  return ti;
 }

可能可以有簡潔的方式,比如不需要引入TypeInfoImp,但是實(shí)際最終證明TypeInfoImp的方式最具靈活性也最能節(jié)省代碼。最起碼,它在自定義的struct或者class就很方便,只要改struct內(nèi)部包含一個(gè)GetTypeInfo()的函數(shù),它就可以被納入TypeOf體系中,非常方便。對于模板類型的TypeInfoImp,就要用到哈希表了。比如,對于std::paira的類型信息,如下實(shí)現(xiàn),

template<typename FstTy, typename SndTy>
struct TypeInfoImp < std::pair<FstTy, SndTy> >
{
static const bool value = true;
typedef TypeInfoImp < std::pair<FstTy, SndTy> > type;
static TypeInfo* GetTypeInfo()
{
ParamsTypeInfo<FstTy, SndTy> args;
return PodPair::LookupTemplateTypeInfo(args);
}
};

提取其類型參數(shù)的const TypeInfo*,生成數(shù)組。用此數(shù)組到PodPair的哈希表里面查找,如果哈希表中以有此類型數(shù)組參數(shù)的對象就返回,否則見創(chuàng)建一個(gè)添加一條哈希條目,然后返回。每一個(gè)泛型類型,比如vector,list,pair都有一個(gè)屬于自己的哈希表。
打完收工。原理很簡單,但是對于工業(yè)級的反射庫,要考慮很多細(xì)節(jié),比如,TypeInfo對象的內(nèi)存管理;怎么為enum類型生成一堆字符串,以支持字符串和enume值的互相轉(zhuǎn)換;生成并保存class的構(gòu)造函數(shù)和析構(gòu)函數(shù)指針;命名空間的支持;仿真C#里面的attribute;如何以最方便的方式生成成員字段或者成員函數(shù)信息等等,一句話,就是他媽的體力活。但是,回報(bào)是很豐盛的,這里的苦力活做完之后,程序的其他地方上,基本上,就沒有什么重復(fù)相似的代碼,一切的體力工作全部就可以壓在類型信息這里了。

相關(guān)文章

  • C++利用 _findfirst與_findnext查找文件的方法

    C++利用 _findfirst與_findnext查找文件的方法

    這篇文章主要給大家介紹了關(guān)于C++利用 _findfirst與_findnext查找文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • C++編譯錯(cuò)誤variable-sized?object?may?not?be?initiali問題

    C++編譯錯(cuò)誤variable-sized?object?may?not?be?initiali問題

    這篇文章主要介紹了C++編譯錯(cuò)誤variable-sized?object?may?not?be?initiali問題及解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • c++ 形狀類Shape(派生出圓類Circle和矩形類Rectangle)

    c++ 形狀類Shape(派生出圓類Circle和矩形類Rectangle)

    通過C++方式,建立一個(gè)形狀類Shape作為基類,派生出圓類Circle和矩形類Rectangle 求出面積并獲取相關(guān)信息
    2020-11-11
  • 一文帶你掌握C++中的移動(dòng)語義和完美轉(zhuǎn)發(fā)

    一文帶你掌握C++中的移動(dòng)語義和完美轉(zhuǎn)發(fā)

    這篇文章主要為大家詳細(xì)介紹了C++中的移動(dòng)語義和完美轉(zhuǎn)發(fā)的相關(guān)知識,文中的示例代碼講解詳細(xì),對我們深入掌握C++有一定的幫助,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • C++封裝靜態(tài)鏈接庫和使用的詳細(xì)步驟

    C++封裝靜態(tài)鏈接庫和使用的詳細(xì)步驟

    這篇文章主要介紹了C++封裝靜態(tài)鏈接庫和使用,本文描述了怎么去把一個(gè)C++程序封裝成一個(gè)靜態(tài)庫并且如何去使用這些靜態(tài)庫,需要的朋友可以參考下
    2022-08-08
  • C語言中常用的幾個(gè)頭文件及庫函數(shù)

    C語言中常用的幾個(gè)頭文件及庫函數(shù)

    這篇文章主要介紹了C語言中常用的幾個(gè)頭文件及庫函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2017-09-09
  • C語言如何實(shí)現(xiàn)一些算法或者函數(shù)你知道嗎

    C語言如何實(shí)現(xiàn)一些算法或者函數(shù)你知道嗎

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)一些算法或者函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 用C語言實(shí)現(xiàn)掃雷小程序

    用C語言實(shí)現(xiàn)掃雷小程序

    這篇文章主要為大家詳細(xì)介紹了用C語言實(shí)現(xiàn)掃雷小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 詳解C++11原子類型與原子操作

    詳解C++11原子類型與原子操作

    這篇文章主要介紹了C++11原子類型與原子操作的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下
    2020-08-08
  • 淺析C++中的多線程編程

    淺析C++中的多線程編程

    這篇文章主要為大家詳細(xì)介紹了C++中的多線程編程,包括創(chuàng)建線程、同步線程、傳遞數(shù)據(jù)給線程以及異常處理等方面,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10

最新評論