RTTI机制与作用(转)
一、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机制与作用(转)的更多相关文章
- C++中的RTTI机制解析
RTTI RTTI概念 RTTI(Run Time Type Identification)即通过运行时类型识别,程序能够使用基类的指针或引用来检查着这些指针或引用所指的对象的实际派生类型. RTTI ...
- [置顶] C++中RTTI机制剖析
C++中要想在运行时获取类型信息,可没有Java中那么方便,Java中任何一个类都可以通过反射机制来获取类的基本信息(接口.父类.方法.属性.Annotation等),而且Java中还提供了一个关键字 ...
- Java反射机制的作用?
Java反射机制的作用? 解答:Java反射机制的作用是: 1)在运行时判断任意一个对象所属的类. 2)在运行时构造任意一个类的对象. 3)在运行时判断任意一个类所具有的成员变量和方法. 4)在运行时 ...
- Java基础知识-简明阐述双亲委派机制及作用
1.双亲委派机制及作用 1.1 什么是双亲委派机制 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类 ...
- 浅谈Java的反射机制和作用
浅谈Java的反射机制和作用 作者:Java大师 欢迎转载,转载请注明出处 很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象 ...
- Java RTTI机制与反射机制
1.1 什么是RTTI? 维基百科的定义:In computer programming, RTTI (Run-Time Type Information, or Run-Time Type Iden ...
- Java反射机制的作用
假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类.那么第一个程序员的代码能否通过编译呢?这是不能通过编译的.利用Java反射的机制,就可以 ...
- C++ 中的RTTI机制详解
前言 RTTI是”Runtime Type Information”的缩写,意思是运行时类型信息,它提供了运行时确定对象类型的方法.RTTI并不是什么新的东西,很早就有了这个技术,但是,在实际应用中使 ...
- Delphi 的RTTI机制浅探3(超长,很不错)
转自:http://blog.sina.com.cn/s/blog_53d1e9210100uke4.html 目录========================================== ...
随机推荐
- Codeforces Round #300 Quasi Binary(DP)
Quasi Binary time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- Xamarin Android真机测试报错
Xamarin Android真机测试报错 Xamarin Android真机测试报错,错误信息为INSTALL_CANCELLED_BY_USER.出现这个错误,通常都是真机上开发者选项设置错误 ...
- JZYZOJ1379天才的约数和 数论 约数和
http://172.20.6.3/Problem_Show.asp?id=1379 易得n=a*b2/b1: 需要注意算出n之后要判断n的约数和是否等于a,这里需要用约数和定理递归,递归前求一下 ...
- vijos p1777 引水入城(bfs+贪心)
引水入城 描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N行M列的矩形,其中每个格子都代表一座城市,每座城市都有一个海拔高度. 为了使 ...
- 【推导】【构造】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem E. Space Tourists
给你n,K,问你要选出最少几个长度为2的K进制数,才能让所有的n位K进制数删除n-2个元素后,所剩余的长度为2的子序列至少有一个是你所选定的. 如果n>K,那么根据抽屉原理,对于所有n位K进制数 ...
- (原创)Stanford Machine Learning (by Andrew NG) --- (week 1) Introduction
最近学习了coursera上面Andrew NG的Machine learning课程,课程地址为:https://www.coursera.org/course/ml 在Introduction部分 ...
- Problem G: 零起点学算法86——Fibonacc
#include<stdio.h> int main(){ ]={,,}; ;i<=;i++) { a[i]=a[i-]+a[i-]; } scanf("%d", ...
- 8VC Venture Cup 2016 - Elimination Round A. Robot Sequence 暴力
A. Robot Sequence 题目连接: http://www.codeforces.com/contest/626/problem/A Description Calvin the robot ...
- 通过Chrome模拟和调试网速慢的情况来限制一些P2P视频网站上传速度占满的情况
- 一个 go 文件服务器 ssdb
file system ssdb go http listen 文件存储到 ssdb gfs | twemproxy | ssdb(master) ssdb(slave) ssdb 连接协议为 red ...