RTTI是属于比较晚加到C++语言中的特性,Microsoft Visual C++编译器提供了可选的开关(/GR)方便开发者选择是否使用这个特性。
除了后来新添加的在编译器上提供的对RTTI的支持之外,有些第三方的库也提供了对RTTI支持方面的软件上的实现,最典型的例子就是MFC中的CRunTimeClass类的引入。其实,要从软件上实现RTTI特性是相当简单的,这点可以借助于C++的另一语言特性——多态来实现。或许正因为如此,对于当初时候引入语言特性的RTTI,标准委员会才会如此纠结。此外,引入RTTI的同时,也会增加了程序员对多路分支选择结构的滥用。
事实上一直有人宣称,语言特性的RTTI是多余的。这应该也是微软编译器将RTTI特性做成可选开关的原因。
软件层面对RTTI的支持不是我要论述的重点。在此主要讨论语言特性对RTTI的支持。RTTI的语言特性实现方式依不同编译器可能会有差别。笔者的实验平台是:VS2008。
typeid和dynamic_cast是对C++对RTTI支持而提供的两个操作符。先详细说明他们的使用方式。
1)dynamic_cast
dynamic_cast < type-id > ( expression )
主要用与实现基类指针与派生类指针之间的转换,是带检查的转换,只对多态性型有效,够则编译器报错。而且dynamic_cast操作符依赖于C++语言的RTTI特性。只有当RTTI开关启用,这样的转换才是有意义的,否则会抛出异常。
在涉及到一个类的继承体系中继承关系的多个类的转换时,有三种转换模式:
downcast
upcast
横向转换
2)typeid
typeid( type-id ) typeid( expression )
这个操作符有些特别,无论RTTI是否启用都能使用。只是当中的 type-id 或expression 是一个带虚函数的类或对象时就有差异了。
A a;typeid(a);-------------------------------//a为多态类型 (*)
RTTI未启用:
对于自定义的带虚函数的类型。编译时警告,运行时抛出异常。
一般类型或 (*) ,静态编译时返回编译器自己构造的typeinfo信息结构体
RTTI启用:
对于 一般类型或 (*) ,没有变化。
除以上情况外,运行时返回指针或引用所指对象的实际类型的typeinfo。
网上查了一些相关资料。在此给一个自己能够说服自己的笼统的导致这种状况的实现机理。
当RTTI未启用时,编译器在编译过程中若遇上 typeid( expression / type-id ), 它先看expression / type-id 是不是 一般类型或 (*) 型,若是,则静态构造一个类型相关的typeinfo.否则,编译报警,运行抛出异常。
当RTTI启用时,编译器在编译过程中若遇上 typeid( expression / type-id ), 它先看expression / type-id 是不是 一般类型或 (*) 型,若是,则静态构造一个类型相关的typeinfo.否则,伴随虚表产生一个项目指向类相关的typeinfo,借此达到动态识别类型的目的。。
--------------------------------------华丽的分隔线——------------------------------------------
这里是找到一篇关于RTTI更详细的论述,深表赞同http://dxwang.blog.51cto.com/384651/79036