RTTI(运行时类型信息),是所有RAD开发工具的基础。
这段时间,因为需要在自己的软件中加入扩展的RTTI功能,于是专门对RTTI进行了研究,现在一些心得写下来。
RTTI是比较新的编程语言提供的能力,C、Fortran、Basic就没有,而现在几乎所有现代的、可视化的编程语言都提供了RTTI功能。C++的标准中也对RTTI作了规定。但相对其它语言而言,C++的RTTI信息是最简单的。
一、RTTI典型的应用需求
1、类型的识别,即能在运行时判断出某对象、表达式等的类型,能判断它们是基本类型(int、string),还是对象,以及它们区别于其它类型的标识;
2、对象的继承关系的运行时判断;
3、在出错处理、内存诊断等处理时的输出信息;
4、基于字符型名称的运行时对象访问、方法调用;
5、对象的自动保存和读入;
6、基于ID或名称的对象自动生成;
7、环境配置的保存和读入;
8、程序自动生成;
二、C++中RTTI的实现
RTTI最直接的实现是通过编程语言的语法支持功能,由编译器自动完成,比如:Delphi等语言就提供了Property关键字。C++语言没有这些语法支持功能,因为C++不是一种RAD语言,可以将VB、Delphi、Java等与之进行对比。C++的RTTI是最简单的,只能获得类名和相关的继承信息;而VB、Delphi、Java等确复杂得多,甚至于支持属性名、方法名、事件名等。
标准C++ 提供了typeid() 操作,以得到类型信息,它的参数可以是一个表达式,可以是一个对象、指针或者引用,通过这个方法,可以得到一个指向常type_info对象,里面包含了这个表达式的类型必要的信息。type_info对象提供的功能有如下这些:
1、name(),可以得到一个包含类型信息的字符串,返回如:"int"、"MyClass"等;
2、before(),用来在类型列表中遍历;
3、==操作,用来判断类型是否相同;
VC中的MFC提供的RTTI实现与C++提供的差不多,但是有一些功能上和实现在的差别,但也只是提供了名称和比较功能。
不能说,这是C++或VC中的缺陷,这是由C++的定位决定了,如果C++加上了复杂的RTTI信息,则C++可能就变成了C#或别的什么语言了。是的,C#增加了比较复杂的RTTI信息,谁让他的主设计者就是从Borland公司过去的呢(这也决定了C++在.NET框架中的会被淘汰的命运,因为它在.NET中没有合适的定位,就象VF被淘汰一样)。
三、RTTI实现的要点
作为一种语言的新特性,RTTI的实现,应有如下要求:
1、必须满足特定语言的定位和要求,不能说,将所有可能的功能加进去就是好东西了;
2、必须是尽可能透明的,RTTI的主要应用在IDE和底层,一般情况下,编程用户不需要了解过多的RTTI细节,比如:作为Delphi用户,他只需要基于属性的访问方法,只需要知道基于组件的保存方法,不需要了解RTTI在其中所起的作用,就象电视机的使用者不需要了解电视机的原理;
3、尽可能轻便,不能因为实现RTTI要耗费大量内存和CPU时间,不能占用太大的程序空间,当然,这个要求是相对的,
4、尽可能高效
4、作为RTTI的实现者,应该尽可能在定义了功能集的情况下,以幽雅的方法实现之。
C++中实现RTTI和执久化是通过宏来完成的,幽雅吗?算是吧。
四、关于几个库中RTTI实现的评价
1、MFC,MFC实现了简单的,与标准C++有区别的RTTI,其实现是通过宏来完成的,同时通过宏来辅助用户完成执久化工作,但执久化
的具体细节要求用户完成。
2、VCL,VCL实现了比较复杂的RTTI,具有关系继承、属性、方法、事件、基于属性的自动对象生成、强大的执久化功能;
3、COM,COM通过类型库定义其RTTI,比VCL还要复杂。
4、QT, QT中实现的RTTI也是比较复杂的,值得说明的是,它提供了一种特别的扩展方法,在编译前,必须将其RTTI信息转换为标准C++语言,个人认为,这是一种不好的方法,虽然我对QT库的评价非常高。特别是它提供的富有特色的CANVAS功能(写到这里,想起以前使用 Oracle的扩展C语言时的痛苦)。
5、WXWINDOW,实现的是比较简单的RTTI。
6、VCF,实现了我所看到的在C++中最全面的RTTI功能,但其性能是一个大问题。
7、OOPS,实现了我所看到的在C++中对象执久化全好的解决方案,但它的扩充性不好在已有标准库的基础上能很好地完成工作,但在增加第三方库的时侯就痛苦了(对了,OOPS中有一篇文章,对RTTI的需求进行了定义,写得非常好http://www.rcs.hu/Articles/RTTI_Part1.htm)。
五、附言
我为什么对RTTI比较关注呢,因为我需要在自己的C++中增加一个轻型的RTTI系统,目前这个体系统正在设计中。