加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 创业 > 正文

c++ 完备的运行时类型信息(动态类型信息)

发布时间:2020-12-30 23:41:56 所属栏目:创业 来源:网络整理
导读:众所周知,码猿写代码,天然要求严谨周密,殊不知想象力也很重要。本座阅码几十年,极端感概许多码猿的脑洞被大大扣留,鲜有人能越雷池一步,出格是c++的同窗,连同委员会的那一坨老头子,都很让人无语至极,出自这些人的作品,都是一个死鱼眼睛样子,千人一
副问题[/!--empirenews.page--]

众所周知,码猿写代码,天然要求严谨周密,殊不知想象力也很重要。本座阅码几十年,极端感概许多码猿的脑洞被大大扣留,鲜有人能越雷池一步,出格是c++的同窗,连同委员会的那一坨老头子,都很让人无语至极,出自这些人的作品,都是一个死鱼眼睛样子,千人一面,毫无灵动之生趣可言。stl,boost这些库都是这样子(固然它们确实可以完成大大都一般使命),更别说其他的库,没有什么让人线人一新之处。

就说说动态范例信息这块,又可能说是反射。天然,说话自己提供的废料type_info就懒得说了,除了证明c++也东施效颦,也能支持动态信息之外,就别无用处了,有谁会正儿八经的用type_info做点正儿八经的工作呢。因此,各路人马纷纷上阵,都要补充c++在运行时范例信息上的缺失。由于范例的反射信息其实太重要,可能说,反射的用武之地太多太多,外貌上许多工作不必要反射,可能字面代码上就看不到反射的陈迹,可是里面的实现,大把大把的反射在发光发烧。c++僵持不在动态信息上给以一点点多余的支持,并不暗示c++就不必要反射了,看看尺度库这个积极回避动多态的规范,是一个奈何的失败作品,嗯,这个往后再谈吧。若是stl一开始就没有云云大力大举排出动多态,你看看就连内存分派的allocator都可以做到静态范例信息内里(最新版的c++终于也要接管多态的allocator,c++界居然一片欢呼激昂,真是悲伤),今时今天的c++就不会在许多规模上处处割地求和。

总的来说,此刻市面上的c++反射库,都是侵入式,都学着mfc那一套,都是要求担任自一个基类Object,然后才气对外提供反射信息的成果,先不说它们提供的范例信息是否完整,这样子就把用途普及限定死在一个很窄很窄的小圈子内里了。这些反射库,1、不能反射根基范例,int、char、double、const char*、……等;2、不能反射非担任自Object的class可能struct,3、也不能反射模板类,好比vector<int>、list<vector<vector<int>>>。固然typeid各样弱鸡,但也非一无可取,最少非侵入、划一、多态。以是,抱负的反射,应该像c++原生的typeid那样无色无味:1、非侵入式的;2、可以对全部的范例都提供反射,根基范例、非Object系的struct可能class、template范例的;3、多态的,只要改范例必要运行时的范例辨认,那么就返回其自己的范例(子类),而非字面上的声明范例;4、支持范例参数,也等于说,以范例转达给该函数时,就返回响应的范例信息工具。

说得详细一点,我们要求的反射库是这样子的。虽然,起主要有一个范例信息工具TypeInfo,内里装满了关于对付范例的全部具体信息。如下所示:可以猜到这种反射下框架,只支持单担任,这是存心的。

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

然后,就要有一个函数TypeOf,应该是两个,一个是无参数的范例模板函数,可以这样挪用,TypeOf<type>();一个是有一个参数的范例模板函数,可以这样挪用,TypeOf(obj)。不管是那一个,其返回功效都是const TypeInfo*。TypeOf的要做到的工作是,对付每一种范例,有且只有一个独一的TypeInfo工具与之对应,不管是template的还长短template的;好比,以下的几个判定必需创立。
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>();
其拭魅这内里的道理也没什么神奇,无非就是trait共同sfine,接下来就所有都是夫役活,就是为每一种范例都专门特化一个具体描写的范例工具,用宏可以节减大量的代码。可是整个反射库,本座前前后后重构了十屡次,此刻也还在重构之中,终究照旧办理了开拓上所碰着的各类工作。好比,序列化(支持指针、支持多态)、工具与xml的交流、工具与json的交流、数据库表读写工具、名目化、Any范例、非侵入式接口、动静发送、字符串天生工具等等。
着实现方法,归纳综合起来,就是引入间接层元函数TypeInfoImp专门用于返回一个范例type,type内里有一个GetTypeInfo()的函数。然后TypeOf挪用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; //又是间接层,对动态范例和非动态范例别离处理赏罚
  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;
 }

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读