下面这篇文章虽然有点老,但对C++的RTTI基本原理讲的比较透彻。
该文章摘自UMLCHINA网站,是台湾一个群体写的,我根据大家比较熟悉的方式,修改了一些名词的说法,如衍生(派生)等,让大家可以方便的阅读。
C++的 RTTI 观念和用途
物泽C++应用小组
  自从1993年Bjarne Stroustrup 〔注1 〕提出有关C++ 的RTTI功能之建议﹐以及C++
的异常处理(exception handling)需要RTTI﹔最近新推出的C++ 或多或少已提供RTTI。然而,若不小心使用RTTI﹐可能会导致软件弹性的降低。本文将介绍RTTI的观念和近况﹐并说明如何善用它。
什么是RTTI﹖
  在C++ 环境中﹐头文件(header file) 含有类之定义(class definition)亦即包含有
关类的结构资料(representational information)。但是﹐这些资料只供编译器(compi
ler)使用﹐编译完毕后并未留下来﹐所以在执行时期(at run-time) ﹐无法得知对象的
类资料﹐包括类名称、数据成员名称与类型、函数名称与类型等等。例如﹐两个类﹐其继承关系如下图:
若有如下指令﹕
            Figure *p;
            p = new Circle();
           Figure &q = *p;
在执行时﹐p 指向一个对象﹐但欲得知此对象之类资料﹐就有困难了。同样欲得知q 所参考(reference) 对象的类资料﹐也无法得到。
  RTTI(Run-Time Type Identification)就是要解决这困难﹐也就是在执行时﹐您想知
道指针所指到或参考到的对象类型时﹐该对象有能力来告诉您。
  随着应用场合之不同﹐所需支持的RTTI范围也不同。最单纯的RTTI包括﹕
●类识别(class identification)──包括类名称或ID。
●继承关系(inheritance relationship)──支持执行时期的「往下变换类型」(downw
ard casting)﹐亦即动态变换类型(dynamic casting) 。
在对象数据库存取上﹐还需要下述RTTI﹕
●对象结构(object layout) ──包括属性的类型、名称及其位置(position或offset
)。
●成员函数表(table of functions)──包括函数的类型、名称、及其参数类型等。
其目的是协助对象的I/O 和持久化(persistence) ﹐也提供调试讯息等。
    若依照Bjarne Stroustrup 之建议〔注1 〕﹐C++ 还应包括更完整的RTTI﹕
●能得知类所实例化的各对象 。
●能参考到函数的源代码。
●能取得类的有关在线说明(on-line documentation) 。
其实这些都是C++ 编译完成时﹐所丢弃的资料﹐如今只是希望寻找个途径来将之保留到执行期间。然而﹐要提供完整的RTTI﹐将会大幅提高C++ 的复杂度﹗
RTTI可能伴随的副作用
  RTTI最主要的副作用是﹕程序员可能会利用RTTI来支持其「复选」(multiple-select
ion)方法﹐而不使用虚函数(virtual function)方法。
  虽然这两种方法皆能达到多态化(polymorphism) ﹐但使用复选方法﹐常导致违反著名的「开放╱封闭原则」(open/closed principle) 〔注2 〕。反之﹐使用虚函数方法则可合乎这个原则,  请看下图﹕
     Circle和Square皆是由Figure所派生出来的子类﹐它们各有自己的draw()函数。当
C++ 提供了RTTI﹐就可写个函数如下﹕
 void drawing( Figure *p )
      {
           if( typeid(*p).name() == "Circle" )
                      ((Circle*)p)  ->  draw();
           if( typeid(*p).name() == "Rectangle" )
                      ((Rectangle*)p) -> draw();
       }
  虽然drawing() 函数也具有多型性﹐但它与Figure类体系的结构具有紧密的相关性。
当Figure类体系再派生出子类时﹐drawing() 函数的内容必须多加个if指令。因而违反
了「开放╱封闭原则」﹐如下﹕
很显然地﹐drawing() 函数应加以修正。
      想一想﹐如果C++ 并未提供RTTI﹐则程序员毫无选择必须使用虚函数来支持drawing() 函数的多型性。于是程序员将draw()宣告为虚函数﹐并写drawing() 如下﹕
     void drawing(Figure *p)
                 {     p->draw();      }
     如此﹐Figure类体系能随时派生类﹐而不必修正drawing() 函数。亦即﹐Figure体
系有个稳定的接口(interface) ﹐drawing() 使用这接口﹐使得drawing() 函数也稳定
﹐不会随Figure类体系的扩充而变动。这是封闭的一面。而这稳定的接口并未限制Figure体系的成长﹐这是开放的一面。因而合乎「开放╱封闭」原则﹐软件的结构会更具弹性﹐更易于随环境而不断成长。
RTTI的常见的     使用场合
      一般而言﹐RTTI的常见使用场合有四﹕异常处理(exceptions handling)、动态转
类型(dynamic casting) 、模块集成、以及对象I/O 。
1.异常处理──  大家所熟悉的C++ 新功能﹕异常处理﹐其需要RTTI﹐如类名称等。
2.动态转类型──  在类体系(class hierarchy) 中﹐往下的类型转换需要类继承的RT
TI。
3.模块集成──  当某个程序模块里的对象欲跟另一程序模块的对象沟通时﹐应如何得知对方的身分呢﹖知道其身分资料﹐才能呼叫其函数。一般的C++ 程序﹐常见的解决方法是──在源代码中把对方对象之类定义(即存在头文件里)包含进来﹐在编译时进行连结工作。然而﹐像目前流行的主从(Client-Server) 架构中﹐客户端(client)的模块对象﹐常需与主机端(server)的现成模块对象沟通﹐它们必须在执行时沟通﹐但又常无法一再重新编译。于是靠标头文件来提供的类定义资料﹐无助于执行时的沟通工作﹐只得依赖RTTI了。
4.对象I/O ──  C++ 程序常将其对象存入数据库﹐未来可再读取之。对象常内含其它
小对象﹐因之在存入数据库时﹐除了必须知道对象所属的类名称﹐也必须知道各内含小对象之所属类﹐才能完整地将对象存进去。储存时﹐也将这些RTTI资料连同对象内容一起存入数据库中。未来﹐读取对象时﹐可依据这些RTTI资料来分配内存空间给对象。
RTTI从那里来﹖
  上述谈到RTTI的用途﹐以及其副作用。这众多争论﹐使得RTTI的标准迟迟未呈现出来。也导致各C++ 开发环境提供者﹐依其环境所需而以各种方式来支持RTTI﹐且其支持RTTI的范围也所不同。  目前常见的支持方式包括﹕
●由类库提供RTTI──例如﹐Microsoft 公司的Visual C++环境。
●由C++ 编译器(compiler)提供──例如﹐Borland C++ 4.5 版本。
●由源代码产生器(code generator)提供──例如Bellvobr系统。
●由OO数据库的特殊预处理器(preprocessor)提供──例如Poet系统。
●由程序员自己加上去。
这些方法皆只提供简单的RTTI﹐其仅为Stroustrup先生所建议RTTI内涵的部分集合而已。相信不久的将来﹐会由C++ 编译器来提供ANSI标准的RTTI﹐但何时会订出这标准呢﹖没人晓得吧﹗
程序员自己提供的RTTI
  通常程序员自己可提供简单的RTTI﹐例如提供类的名称或识别(TypeID)。最常见的方法是﹕为类体系定义些虚函数如Type_na() 及Isa() 函数等。请先看个例子﹕
 class Figure  { };
 class Rectangle : public Figure   { };
 class Square : public Rectangle
        {    int data;
            public:
              Square() { data=88; }
              void Display()  { cout << data << endl; }
          };
 void main()
       {   Figure *f = new Rectangle();

转载于:https://blog.51cto.com/dxwang/79036

[转]c++中RTTI的观念和使用相关推荐

  1. c++中RTTI的观念和使用

    下面这篇文章虽然有点老,但对C++的RTTI基本原理讲的比较透彻. 该文章摘自UMLCHINA网站,是台湾一个群体写的,我根据大家比较熟悉的方式,修改了一些名词的说 法,如衍生(派生)等,让大家可以方 ...

  2. jiffies:内核中的时间观念

    jiffies在内核中是一个全局变量,声明包含在#include <linux/jiffies.h>中, 几个内核中常用的的概念: 1. HZ 内核常量,ARM架构HZ=100,X86架构 ...

  3. (转)C++的 RTTI 概念和用途

    自从1993年Bjarne Stroustrup [注1 ]提出有关C++ 的RTTI功能之建议﹐以及C++的异常处理(exception handling)需要RTTI:最近新推出的C++ 或多或少 ...

  4. C++的RTTI基本原理

    下面这篇文章虽然有点老,但对C++的RTTI基本原理讲的比较透彻. C++的 RTTI 观念和用途 物泽C++应用小组    自从1993年Bjarne Stroustrup [注1 ]提出有关C++ ...

  5. c语言中很多中括号由外向里,浅谈C语言中的类型声明

    文章目录 [隐藏] 新年第一更!之前群友问了一个 C语言 问题,即int(*(*p)()).int *(*p)()和int *(*p())的区别在哪里.确实,有时C语言的类型声明是很魔性的,看着也很令 ...

  6. 影响程序员生涯的三个错误观念,你千万不要犯!

    程序员在社会上,到底是怎样一个生活群体?是否能找到自己方向?其实,路一直都在那里,只是你看不到而已! 当初的你,可能一直被一些技术牵着鼻子走,并不是自己在做着自己想做的,而是被技术推到了现在这样子.想 ...

  7. 影响程序员生涯的三个错误观念,你千万不要犯

    转载自   影响程序员生涯的三个错误观念,你千万不要犯 程序员在社会上,到底是怎样一个生活群体?是否能找到自己方向?其实,路一直都在那里,只是你看不到而已! 当初的你,可能一直被一些技术牵着鼻子走,并 ...

  8. 中职计算机英语教师教学总结,中职计算机教师教学工作总结 (3000字).doc

    中职计算机教师教学工作总结 (3000字) PAGE3 / NUMPAGES3 中职计算机教师教学工作总结 (3000字) 2013~2014学年教学工作总结 本学期,我担任Z1322,Z1323,Z ...

  9. 中职计算机教师考核工作总结,中职计算机教师教学工作总结

    中职计算机教师教学工作总结 指缝很宽,时间太瘦,悄悄从指缝间溜走,回顾坚强地走过的这段时间,取得的成绩实则来之不易,先准备一份教学总结吧.拿起笔的时候却发现不知道写什么,以下是小编为大家收集的中职计算 ...

  10. 计算机在教育中的应用的基本现状,现代教育技术应用的现状与发展

    现代教育技术是教育现代化的重要标志,是实现教育现代化的重要条件.21世纪的国际竞争是经济的竞争,科技实力的竞争,归根结底是人才的竞争.随着信息技术的高速发展和广泛应用,现代教育技术的发展也十分迅猛,并 ...

最新文章

  1. SQL Server的数据库连接的极限在哪儿?
  2. 禁止修改varchar到int|[运维规范]
  3. Python对Excel的读操作(完成)
  4. oracle中ora-02049,ORA-02049 ‘timeout: distributed transaction waiting for lock’ 解决
  5. sklearn之逻辑回归和岭回归
  6. Leetcode每日一题:168.excel-sheet-column-title(Excel表名称)
  7. 在英雄联盟地图中寻找“数据结构的大门”
  8. Java read failed_android-获取java.io.IOException:读取失败,套接...
  9. 不吹不黑聊聊前端框架--尤雨溪Live整理
  10. 全国省市区行政编码数据表 sql格式
  11. distpicker使用记录
  12. FrontEnd前端文件架构
  13. visual studio 2015 启动停止工作, 问题事件名称:APPCRASH 应用程序名:devenv.exe 故障模块名称:
  14. POJ1201/ZOJ1508/HDU1384 Intervals(spfa解差分约束问题)
  15. 如何访问集群中指定的服务器,【Nacos源码之配置管理 六】集群模式下服务器之间是如何互相感知的...
  16. window系统 任务计划程序
  17. Systemd基础篇:workingdirectory事前不创建会导致的问题
  18. weblogic部署jdk版本问题
  19. 国家电网公司“SG186工程”的含义
  20. Flash8平铺网页背景图文教程

热门文章

  1. C语言中用二进制输出一个数字
  2. 为何MAC的JDK/JRE大小这么小?
  3. 博客积分为0,这是又出错了?
  4. SHELL判断文件是否包含某个字串
  5. 百度网盘,莫名其妙把文件删除了
  6. 《史记》记载的喝粥延命内容
  7. UBUNTU中更改文件的打开方式
  8. java虚拟机内存_java虚拟机内存区域的划分以及作用详解
  9. python中的计时器timeit_python中的计时器:timeit
  10. python 高并发 tomcat_TOMCAT 高并发配置