【摘要】
       RTTI(Run-Time Type Identification)是面向对象程序设计中一种重要的技术。

现行的C++标准对RTTI已经有了明白的支持。

只是在某些情况下出于特殊的开发须要,我们须要自己编码来实现。本文介绍了一些关于RTTI的基础知识及其原理和实现,并分析比較三者是线上的差异与联系。

【正文】

RTTI 的需求

和非常多其它语言一样,C++是一种静态类型语言。其数据类型是在编译期就确定的,不能在执行时更改。然而因为面向对象程序设计中多态性的要求,C++中的指针或引用(Reference)本身的类型,可能与它实际代表(指向或引用)的类型并不一致。

有时我们须要将一个多态指针转换为事实上际指向对象的类型。就须要知道执行时的类型信息。这就产生了执行时类型识别的要求。

C++对RTTI的支持

C++提供了两个keywordtypeid和dynamic_cast,一个类type_info来支持RTTI。

  dynamic_cast操作符:它同意在执行时刻进行类型转换,从而使程序可以在一个类层次结构安全地转换类型。dynamic_cast提供了两种转换方式。把基类指针转换成派生类指针,或者把指向基类的左值转换成派生类的引用。

见下例讲述:

void company::payroll(employee *pe) {
//对指针转换失败,dynamic_cast返回NULL
if(programmer *pm=dynamic_cast(pe)){
pm->bonus();
}
}void company::payroll(employee &re) {
try{
//对引用转换失败的话,则会以抛出异常来报告错误
programmer &rm=dynamic_cast(re);
pm->bonus();
}
catch(std::bad_cast){
}
}

这里bonus是programmer的成员函数,基类employee不具备这个特性。

所以我们必须使用安全的由基类到派生类类型转换,识别出programmer指针。

 typeid操作符:它指出指针或引用指向的对象的实际派生类型。
       比如:

employee* pe=new manager;
typeid(*pe)==typeid(manager) //true 

typeid能够用于作用于各种类型名,对象和内置基本数据类型的实例、指针或者引用,当作用于指针和引用将返回它实际指向对象的类型信息。typeid的返回是type_info类型。
       type_info类:这个类的确切定义是与编译器实现相关的。以下是《C++ Primer》中给出的定义(參考资料[2]中谈到编译器必须提供的最小信息量):

class type_info {
private:
type_info(const type_info&);
type_info& operator=( const type_info& );
public:
virtual ~type_info();
int operator==( const type_info& ) const;
int operator!=( const type_info& ) const;
const char* name() const;
};

详见:http://bbs.csdn.net/topics/40414128

三者比較:

宏能够在编译前用字符替换的办法展开,减轻程序猿反复编码的工作量。

c++的范型(模版)也是在编译时确定终于的程序样式。他用的办法是编译时确定类型信息。

RTTI是执行期类型信息,能够在执行时得到对象的类型信息。

我们考察一个程序,为了说明问题,我特意找了一个简单的程序,这个程序比較a和b,假设a大于b就交换他们。可是。a、b的类型并不确定可能是字符串也可能是整数还可能是复数。为了简洁和不至于造成过的混淆,我不使用操作符重载。假定不论什么操作都是基于对象方法的,为了完毕这个函数。a、b必须支持compare(比較)和swape(交换)方法。

我们不清楚a、b的类型,假设有3种类型我们就必须写3个函数吗?那太累人了。我们用来定义这个函数好了。
#define exchange(a,b) if(a.compare(b))a.swape(b);
这样我们在使用的时候就能够直接使用exchange宏来表达这个函数,并且能够适应各种类型,仅仅要他们都支持这两个函数就能够。

我们还能够用范型来实现这个函数
template<typename T>
void exchange(T &a, T &b)
{
  if(a.compare(b))a.swape(b)
}
我们相同达到了目的。

假设编译器支持丰富的RTTI,我们还能够用脚本语言的方式来实现他们。
exchange(a, b)
{
  if(a.compare(b))a.swape(b);
}

上面三种方式区别在哪里呢?
第一种。使用字符替换的方式,在编译前展开宏,使之成为程序中的一段代码。

另外一种,在编译时。确定调用函数的參数的类型,并自己主动生成一个这个类型的暂时函数。
第三种。在执行时依据參数的类型确定是否可以执行这段程序。
前2种都是在编译时确认的。第三种是在执行时确定的。
在程序设计中有着大量的反复代码,我们须要一种方法来提高效率,可是为什么看着结构类似的程序须要反复代码呢?最重要的原因是,传统的程序中实体(函数、变量、属性等等)在编译时都须要内存中一块确定的地址(或者相对基址的偏移)来指代。这时cpu处理方式的内在要求,而这个和程序设计时依照名字引用的思维习惯是不一致的。
我们能够用宏和模版来取代手工对每一个类型的特化,可是在程序中仍然是使用地址来指代实体的。实际上每一个类型的特化程序依旧存在,仅仅是在程序设计外观上不可见了。
第三种方式。使用RTTI。程序中的实体都不再是确定的地址来指代,而是通过字符串名称(或者实体表)来指代,在执行时依据名称来特化。这样的方法和前2个方法是本质的不同。

使用RTTI能够在非常大程度上减轻宏和静态模版带来的副作用,使程序具有更加优雅的外观。
可是。C++的宏和静态模版也不是一无是处。他用在对效率更加严格场合是很合适的。

转载于:https://www.cnblogs.com/llguanli/p/8286541.html

C++ 宏、范型和RTTI 浅析相关推荐

  1. 简述结构化范型和面向对象范型的要点,并分析他们的优缺点

    结构化范型和面向对象范型的要点及优缺点 要点 优点 缺点 结构化范型 (1)结构化范型也称生命周期方法学,属于传统方法学.(2)传统的软件开发方法大部分采用瀑布模型.这种模型要求每一阶段都以前一阶段形 ...

  2. 简述结构化范型和面向对象范型的要点,并分析它们的优缺点。

    答: ( 1 )结构化范型 ① 要点 结构化范型属于传统方法学.传统的软件开发方法大部分采用瀑布模 型.这种模型要求每一阶段都以前一阶段形成的文档为基础完成工作. 每一阶段将要完成时,都要求开发人员进 ...

  3. 分析 C# 2.0 新特性 -- 范型(Generics)

    分析 C# 2.0 新特性 -- 范型(Generics) 作者:梁振[MS-MVP]   范型是提高面向对象程序多态性设计衍生的. 1,C# 多态性设计回顾和展望 在引入范型这个概念之前,回顾一下1 ...

  4. Java 数组转型和范型

    今天写代码遇到一个奇怪的问题,代码结构如下: [java] view plaincopy print? ArrayList<String> list = new ArrayList< ...

  5. Java不支持创建范型数组分析

    我想这个问题的答案是:因为这样做会破坏类型安全.核心的问题在于Java范型和C#范型存在根本区别:Java的范型停留在编译这一层,到了运行时,这些范型的信息其实是被抹掉的:而C#的范型做到了MSIL这 ...

  6. 范型 DAO范型的应用

    当你偶然路过这里时,我假定你已经很明白 java 中范型和 DAO 模式了.当然,我也会顺便唠叨几句范型和 DAO 模式,只是它们不会这篇随笔的重点.我早先在 DW 上看到一篇蛮不错的文章 不要重复 ...

  7. J2SE5.0新特性之范型编程

    J2SE5.0新特性之范型编程 晁岳攀 smallnest@163.com 本章主要参考sun公司文档. C++程序员对范型编程肯定不陌生,尤其在STL大行其道的时候,C#2.0也将实现范型编程的功能 ...

  8. C++ RTTI及“反射”技术

    RTTI 是"Runtime Type Information"的缩写,意思是:运行时类型信息.它提供了运行时确定对象类型的方法.本文将简略介绍 RTTI 的一些背景知识.描述 R ...

  9. RTTI(Runtime Type Information )

    RTTI 是"Runtime Type Information"的缩写,意思是:运行时类型信息.它提供了运行时确定对象类型的方法.本文将简略介绍 RTTI 的一些背景知识.描述 R ...

最新文章

  1. 神了!阿里资深大牛熬夜整理Python学习路线,终于开放了
  2. 统计学Java_【gloomyfish】基于Java的统计学计算结果
  3. cannot import caffe
  4. Repeater\DataList\GridView实现分页,数据编辑与删除
  5. 接oracle私活价格,也来记录一下第一次接私活的体验
  6. 趣味物理中的计算机科学,【趣味物理】10个有趣的科学实验,揭示物理原理。...
  7. leetcode组队学习——动态规划
  8. linux下播放wma格式,Ubuntu 20.04中使Rhythmbox支持WMA格式文件播放
  9. NATAPP vscode SSH远程连接Linux服务器出现couldn‘t establish connection
  10. day7_操作excel的三种方式
  11. centOS6添加开机启动
  12. 在线一键重装Win11系统步骤
  13. 详解DNS服务、DNS解析、DNS劫持和污染
  14. 小数化分数(C++ 代码讲解很详细)
  15. 美国人日常生活中常用的五星级句子
  16. 下载spotify音乐_如何将Google Maps音乐控件用于Spotify,Apple Music或Google Play音乐
  17. 强大的多语言版本在线图片处理网站
  18. 什么是DTO、VO、BO、PO、DO、POJO
  19. 快消企业数字化转型如何落地
  20. QTabWidget 样式例子

热门文章

  1. Github Action 快速构建 Electron 应用
  2. Linux C 预处理详解
  3. vs2008打开vs2010工程项目
  4. linux下gdb常用的调试命令
  5. React开发(252):react项目理解 ant design spining加载中
  6. 前端学习(3169):react-hello-react之删除一个todoList
  7. 前端学习(2947):node.js使用
  8. [vue-cli]不用vue-cli,你自己有搭建过vue的开发环境吗?流程是什么?
  9. 工作总结17:组件封装思想
  10. 前端学习(2207):Vue-store文件夹的目录结构