一、RTTI(Run-Time Type identification),通过运行时类型信息,程序能够使用基类的指针或引用来检查这些指针或引用所指向的对象的实际派生类型。面向对象的编程语言,想C++,Java,delphi都提供了RTTI的支持。RTTI并不是什么新技术,很早就有了,他主要提供了运行时确定类对象类型的方法。最近有用到这个RTTI,对它进行了一番小研究,下面做个小小的总结吧!
在C++ 环境中﹐头文件(header file) 含有类之定义(class definition)亦即包含有关类的结构资料(representational information)。但是﹐这些资料只供编译器(compiler)使用﹐编译完毕后并未留下来﹐所以在执行时期(at run-time) ﹐无法得知对象的类资料﹐包括类名称、数据成员名称与类型、函数名称与类型等等。
例如﹐两个类﹐Circle继承Shape类,若有如下指令﹕

 Shape*p;
p = new Circle();
Shape&q = *p;

在执行时﹐p 指向一个对象﹐但欲得知此对象之类资料(这里没有实现虚函数)﹐就有困难了。同样欲得知q 所参考(reference)对象的类资料﹐也无法得到。

RTTI(Run-Time Type Identification)的存在就是要解决这困难﹐也就是在执行时﹐您想知道p指针所指到或参考到的对象类型﹐到底是Circle呢还是Shap类呢?该对象有能力来告诉您。

RTTI提供了两个十分有用的操作符:
(1)typied操作符,返回指针和应用的实际类型(比如使用typeid(a).name()就能知道变量a是什么类型的)。
(2)dynamic_cast操作符,将基类类型的指针或引用安全地转换为派生类型的指针或引用。在C++中存在虚函数,也就存在了多态性,对于多态性的对象,在程序编译时可能会出现无法确定对象的类型的情况。当类中含有虚函数的时候,其基类的指针可以指向任何派生类的对象,这时就有可能不知道基类到底指向的是那个对象的情况,类型的确定要在运行时利用运行时类型标识做出。为了获得对象的类型可以使用typeid函数。
      typeid函数:主要作用是让用户知道当前的变量是什么类型的,并且对于自己定义的结构体,类都能很好的支持。用法如下:

 class A{};
A *a=new A;
cout<<typeid(a).name()<<endl;
cout<<typeid(*a).name()<<endl;
 

运行结果:

RTTI的实现:
例如 Circle和Square都集成Shape类﹐它们各有自己的draw()函数。当C++ 提供了RTTI﹐就可写个函数如下﹕

  void drawing( Shape *p )
{
if( typeid(*p).name() == "Circle" )
((Circle*)p) -> draw();
if( typeid(*p).name() == "Rectangle" )
((Rectangle*)p) -> draw();
}

虽然drawing() 函数也具有多型性﹐但它与Figure类体系的结构具有紧密的相关性。当shape类体系再派生出子类时﹐drawing() 函数的内容必须多加个if指令。因而违反
了「开放╱封闭原则」﹐如下﹕很显然地﹐drawing() 函数应加以修正。
      想一想﹐如果C++ 并未提供RTTI﹐则程序员毫无选择必须使用虚函数来支持drawing() 函数的多型性。于是乎写下:virtual void drawing()﹕
     void drawing(Figure *p)
      {    
                 p->draw();     
}
     如此﹐Figure类体系能随时派生类﹐而不必修正drawing() 函数。亦即﹐Figure体系有个稳定的接口(interface) ﹐drawing() 使用这接口﹐使得drawing() 函数也稳定

﹐不会随Figure类体系的扩充而变动。这是封闭的一面。而这稳定的接口并未限制Figure体系的成长﹐这是开放的一面。因而合乎「开放╱封闭」原则﹐软件的结构会更具弹性﹐更易于随环境而不断成长。

二、一般而言﹐RTTI的常见使用场合有四﹕

1.异常处理

大家所熟悉的C++ 新功能﹕异常处理﹐其需要RTTI﹐如类名称等。

2.动态转类型

在类体系(class hierarchy) 中﹐往下的类型转换需要类继承的RTTI。

3. 模块集成

当某个程序模块里的对象欲跟另一程序模块的对象沟通时﹐应如何得知对方的身分呢﹖

知道其身分资料﹐才能呼叫其函数。一般的C++ 程序﹐常见的解决方法是──在源代码中把对方对象之类定义(即存在头文件里)包含进来﹐在编译时进行连结工作。然而﹐像目前流行的主从(Client-Server) 架构中﹐客户端(client)的模块对象﹐常需与主机端(server)的现成模块对象沟通﹐它们必须在执行时沟通﹐但又常无法一再重新编译。于是靠标 头文件来提供的类定义资料﹐无助于执行时的沟通工作﹐只得依赖RTTI了。

4.对象I/O

C++ 程序常将其对象存入数据库﹐未来可再读取之。对象常内含其它小对象﹐因之在存入数据库时﹐除了必须知道对象所属的类名称﹐也必须知道各内含小对象之所属类﹐才能完整地将对象存进去。储存时﹐也将这些RTTI资料连同对象内容一起存入数据库中。未来﹐读取对象时﹐可依据这些RTTI资料来分配内存空间给对象。

博文资料参考:

http://www.cnblogs.com/lzjsky/archive/2010/11/23/1885771.html

http://blog.csdn.net/pi9nc/article/details/21742355

RTTI机制与作用(转)的更多相关文章

  1. C++中的RTTI机制解析

    RTTI RTTI概念 RTTI(Run Time Type Identification)即通过运行时类型识别,程序能够使用基类的指针或引用来检查着这些指针或引用所指的对象的实际派生类型. RTTI ...

  2. [置顶] C++中RTTI机制剖析

    C++中要想在运行时获取类型信息,可没有Java中那么方便,Java中任何一个类都可以通过反射机制来获取类的基本信息(接口.父类.方法.属性.Annotation等),而且Java中还提供了一个关键字 ...

  3. Java反射机制的作用?

    Java反射机制的作用? 解答:Java反射机制的作用是: 1)在运行时判断任意一个对象所属的类. 2)在运行时构造任意一个类的对象. 3)在运行时判断任意一个类所具有的成员变量和方法. 4)在运行时 ...

  4. Java基础知识-简明阐述双亲委派机制及作用

    1.双亲委派机制及作用 1.1 什么是双亲委派机制 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类 ...

  5. 浅谈Java的反射机制和作用

    浅谈Java的反射机制和作用 作者:Java大师 欢迎转载,转载请注明出处 很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象 ...

  6. Java RTTI机制与反射机制

    1.1 什么是RTTI? 维基百科的定义:In computer programming, RTTI (Run-Time Type Information, or Run-Time Type Iden ...

  7. Java反射机制的作用

    假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类.那么第一个程序员的代码能否通过编译呢?这是不能通过编译的.利用Java反射的机制,就可以 ...

  8. C++ 中的RTTI机制详解

    前言 RTTI是”Runtime Type Information”的缩写,意思是运行时类型信息,它提供了运行时确定对象类型的方法.RTTI并不是什么新的东西,很早就有了这个技术,但是,在实际应用中使 ...

  9. Delphi 的RTTI机制浅探3(超长,很不错)

    转自:http://blog.sina.com.cn/s/blog_53d1e9210100uke4.html 目录========================================== ...

随机推荐

  1. Express使用MongoDB常用操作

    const MongoClient = require('mongodb').MongoClient const url = "mongodb://localhost:27017" ...

  2. 连接LilyPad之Windows平台的驱动

    连接LilyPad之Windows平台的驱动 LilyPad和其他的Arduino控制板的不同之处是它是为电子织物和可穿戴设计的.那么,它的大小就必须要紧凑.所以,它并没有板载其他大多数板子都具有的U ...

  3. 【BZOJ 2802】 2802: [Poi2012]Warehouse Store (贪心)

    2802: [Poi2012]Warehouse Store Description 有一家专卖一种商品的店,考虑连续的n天.第i天上午会进货Ai件商品,中午的时候会有顾客需要购买Bi件商品,可以选择 ...

  4. POJ2068 Nim 博弈论 dp

    http://poj.org/problem?id=2068 博弈论的动态规划,依然是根据必胜点和必输点的定义,才明白过来博弈论的dp和sg函数差不多完全是两个概念(前者包含后者),sg函数只是mex ...

  5. 【jzyzoj】【p1320 patrol】 巡逻(网络流最小割例题)

    描述 Description FJ有个农场,其中有n块土地,由m条边连起来.FJ的养牛场在土地1,在土地n有个新开张的雪糕店.Bessie经常偷偷溜到雪糕店,当Bessie去的时候,FJ就要跟上她.但 ...

  6. 求图的强连通分量--tarjan算法

    一:tarjan算法详解 ◦思想: ◦ ◦做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间 ...

  7. 2014 linux

    [51CTO精选译文]每年大概12月前后,人们喜欢给出种种预测,预言他们认为未来一年技术界会出现什么样的变化.本文也不例外,只不过侧重介绍2014年值得关注的十大最受关注的Linux发行版(桌面版或移 ...

  8. luci范例

    转自:http://www.cnblogs.com/souroot/p/4511760.html LuCI (Lua Configiration Interface) 是OpenWRT 的Web 管理 ...

  9. H5 manifest离线缓存

    请跳转我的有道云笔记查看: http://note.youdao.com/noteshare?id=caaf067c6e38820ba8f87b212c2327a9&sub=23E0F8F7A ...

  10. asp.net Mvc Area 找到多个与名为相同的控制器匹配的类型 请通过调用含有“namespaces”参数

    MVC中的Area的区域的时候,在一个Area中定义了一个Home控制器,在启动的时候, 找到多个与名为"Home"的控制器匹配的类型.如果为此请求("{controll ...