跟我学c++高级篇——反射的基本原理

222 篇文章 92 订阅

一、反射的发展

在前面分析了反射的概念和应用场景。基本对反射的应用有了一个明白的理解。这就回到一个初始的问题,反射是如何在动态运行时拿到数据的类型并展开各种的操作的。也就是说,最基础的仍然在于数据类型的判断和获取。在早期的程序的从编写到编译到加载到机器内存时,由于硬件的限制,需要不断的节省占用空间。包括现在大家熟悉的空间换时间,时间换空间的概念都和机器的硬件配置或多或少有着关系。
假设,终端(PC、手机及其它)的内存、CPU、IO速度都是没有限制的,那么很多计算机的技术其实都失去了意义。包括操作系统的开发也会变得轻松简单,很多所谓的中间件都成了笑话。所谓一些软件的优化都可以转到硬件上去控制,这样,软件编程就会变得简单很多。可现实是骨感的,这些只能是在梦里想想罢了。
反射其实和硬件就有一定关系,早期的程序的编写语言为什么是C/C++的天下?就是因为其处理PC资源更强大。在强类型语言中,数据类型基本在定义时就已经为编译器知晓,所以这部分不是问题。但是反射恰恰是反过来,如果不知道传进来的是一种什么类型,如何获取它甚至在此基础上进一步应用呢?
很简单,在编写代码时,手动或者自动在每个对象后面加上其属性说明不就可以了。类似于XML或者JSON,一看就明白了。而运行的代码中只要分析传入对象的属性解析出相关的数据类型即可。但是,这在原来寸土寸金的资源上,每一个字节都是要压榨的,还想着莫名的增加不少辅助信息,这真是简直无法忍受。
但是,随着技术的发展,现在,这些硬件资源已经不再是根本性的瓶颈了,所以反射是不是可以搞起来,c++做为一种已经生命期比较长的语言,是不是也要支持一下?

二、反射的基本原理

通过上面的分析可以看出,反射的基本原理就是在运行前的某个时期(如编译期)把相关的类型信息处理后存储到执行文件中。这些类型信息,包括在提到的属性、成员函数、类名称、大小、偏移地址等等(也可以叫做元数据)。那么在处理这些类型信息时又有两种办法,即侵入式和非侵入式。
所谓侵入式,就是把相关信息增加到具体的数据类型中,比如在一个类对象里,在编译时增加很多的相关信息,甚至也可以直接强迫程序员手动在编码时就写好。但这样做,麻烦就来了,如果修改怎么办,一个很简单的修改,可能会影响很多地方。
那就有另外一种方式,非侵入式,就是把这些信息专门写入额外的一个文件或者一个类中去。这样做的好处就显尔易见了,修改方便了,但是,数据量大了很多。
对于电脑来说,它并不知道什么int,char,Class,Struct…这些概念,它只会根据编译的过程处理这些类型到指定的地址空间即可。如果这些映射空间地址的基地址,大小,长度,每个地址(属性或者方法等)的间距(内存对齐)等都知道的话,反射就可以进行了。
有兴趣的可以深入看一下Java虚拟机相关的书籍,就可以理解的更清晰明白。
如果用一个不太恰当的比喻就是制图,制图人员一开始根据需求画出图来,而复制图的人,只需要按照图的具体的标记和相关尺寸等即可轻松的再画出同样的一张图。

三、反射的特点和优化

反射的特点很鲜明,就是把必须原来静态定义才能使用的对象可以动态来根据情况来生成。并可以根据这些来进行代码的运行时装配,减少了各个源码间的相互制约。但问题是,反射一般会破坏掉面向对象封装中的代码控制权限,比如可以对Private的属性进行操作,这其实是一种不安全的行为。同时,反射由于需要处理的流程长,需要消耗不少的系统资源。所以在考虑效率的某些场景下,反射就尽量要避免应用。
当然,有问题就会有优化,可以采用一些预加载或者缓存的方式来处理反射慢的问题,只是这样可能会消耗一定的空间资源。但是不管如何优化,对于一些内联函数的处理和一些方法的直接调用上,反射都有着无法避免的劣势,这也是反射一定会慢的一个重要原因。
即使是放弃了方法等的安全检验甚至直接调用函数,其最好的情况也仍然无法和静态语言的直接应用快捷。
在c++中,对反射的机制支持是非常弱小的,静态反射的支持,即在编译期的自省,在不断的完善;但在动态反射的支持上,目前还需要耐心的等待。

四、总结

对反射在c++中的应用,大多数开发者可以忽略它。对国内来说更是如此,有兴趣可以搞一搞,如果没有兴趣的话,大可以束之高阁,等有需要的时候儿再拿起来现炒现卖,单纯在上层应用,肯定不会有多复杂。不用在过于担心会不会被标准扔得远远的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值