一、定义:RTTI:Run Time Type Identification ,执行时类型识别:指程序可以使用基类的指针或引用来检索其所指对象的实际派生类型。
二、使用方式:C++中有两个操作符提供RTTI:
(1)typeid 操作符:返回指针或引用所指对象的实际类型。
(2)dynamic_cast 操作符:将基类类型的指针或引用安全地转换为派生类型的指针和引用。
 :此二操作符仅仅为带有一个或多个虚函数的类返回动态类型信息----即在执行时执行RTTI操作符;对于其它类型则返回静态类型的信息---即在编译时计算RTTI操作符。
三、详细介绍
(1)typeid
头文件
:# include<typeinfo>
语法--两种形式:typeid (type) 、typeid (expression)即随意表达式或类型名。 常见的用途:比較两个表达式的类型。或者将表达式的类型与特定类型相比較。
typeid返回类型const type_info&
详细定义例如以下:
  1. class type_info{
  2. public:
  3. virtul ~type_info();
  4. bool operator == (const type_info&rhs)const;
  5. bool operator != (const type_info&rhs)const;
  6. bool before(const type_info&rhs)const;
  7. const char* name()const;
  8. private:
  9. type_info(const type_info& rhs);
  10. type_info& operator=(const type_info& rhs);
  11. }
接口说明
operator ==和operator!=:比較操作符。返回两个类型是否为(或不为)同一类型(注:基类和派生类不为同一类型! )。
before:若在类型排序中。该类型先于rhs的类型则返回true。 name:返回类型相应的名字(详细所用的值,依赖于详细编译器)(以\0结束的字符串)。
注意:type_info类的默认构造函数和复制构造函数以及赋值操作符都定义为private,故不能定义或复制type_info类型的对象。程序中创建type_info对象的唯一方法是使用typeid操作符。 样例:(来源
  1. #include <iostream>
  2. #include <typeinfo>
  3. using namespace std;
  4. struct Base {};
  5. struct Derived : Base {};
  6. struct Poly_Base {virtual void Member(){}};
  7. struct Poly_Derived: Poly_Base {};
  8. int main() {
  9. int a;
  10. int * pa;
  11. cout << "int is: " << typeid(int).name() << endl;
  12. cout << "  a is: " << typeid(a).name() << endl;
  13. cout << " pa is: " << typeid(pa).name() << endl;
  14. cout << "*pa is: " << typeid(*pa).name() << endl << endl;
  15. Derived derived;
  16. Base* pbase = &derived;
  17. cout << "derived is: " << typeid(derived).name() << endl;
  18. cout << "*pbase is: " << typeid(*pbase).name() << endl;
  19. cout << "same type? ";
  20. cout << ( typeid(derived)==typeid(*pbase) ) << endl << endl;
  21. Poly_Derived polyderived;
  22. Poly_Base* ppolybase = &polyderived;
  23. cout << "polyderived is: " << typeid(polyderived).name() << endl;
  24. cout << "*ppolybase is: " << typeid(*ppolybase).name() << endl;
  25. cout << "same type? ";
  26. cout << ( typeid(polyderived)==typeid(*ppolybase) ) << endl << endl;
  27. return 0;
  28. }
执行结果:(尝试了两个编译环境:g++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)  和 VC6.0)
G++结果:
VC6.0结果:
注:尽管 typeid(*ppolybase)返回派生类类型。可是 typeid(ppolybase)依然是返回基类指针类型。 同理,引用相似:假设r是引用,typeid(r)返回派生类类型,typeid(&r)则依然返回基类类型。
注意到:两个编译环境的执行结果不一样---即typeid在不同编译环境下返回的结果是不一致的!

为什么会这样呢?
由于:标准C++规定,type_info类的确切定义随编译器而变化,仅仅要保证全部的实现提供以上的基本操作即可(见类定义)。即详细实现细节。各编译器厂商可自行决定。
注:在VC6.0执行时,记得把编译选项加上“/GR“ ,否则编译时会出现Warning(project--设置--C/C++---project选项)。 由于VC6.0默认不开启RTTI。 (2)dynamic_cast
语法形式:dynamic_cast<T>(v) ,将对象 v 转换为类型T的对象。
前提:v 要么为指向其派生类对象的基类指针,要么为引用其派生类对象的基类对象。否则。v 返回NULL(为指针时)或抛出std::bad_cast(在头文件<typeinfo>中定义)异常(为引用类型时);而T为所期望的派生类指针类型或派生类引用类型。 且。v指向的基类里必须包括虚函数,即多态类型。否则编译出错。 经常使用写法:
I、Poly_Derived* derivedPtr = dynamic_cast<Poly_Derived*>(ppolybase);//转换为指向Poly_Derived 型的指针,失败返回NULL;
II、Poly_Derived& derivedRef = dynamic_cast<Poly_Derived&>(polyderived); //转换为Poly_Derived 引用,失败时抛出bad_cast异常。
详细见样例:
  1. #include <iostream>
  2. #include <typeinfo>
  3. using namespace std;
  4. struct Poly_Base {virtual void Member(){}};
  5. struct Poly_Derived: Poly_Base {};
  6. int main() {
  7. Poly_Derived polyderived;
  8. Poly_Base* ppolybase = &polyderived;
  9. Poly_Base& rpolybase = polyderived;
  10. if(Poly_Derived* derivedPtr = dynamic_cast<Poly_Derived*>(ppolybase))//base pointer
  11. {
  12. cout<<"dynamic_cast pointer success."<<endl;
  13. }
  14. else
  15. {
  16. cout<<"dynamic_cast pointer fail!"<<endl;
  17. }
  18. try{
  19. const Poly_Derived& derivedRef = dynamic_cast<const Poly_Derived&>(rpolybase);
  20. cout<<"dynamic_cast reference success."<<endl;
  21. }catch(bad_cast){
  22. cout<<"dynamic_cast reference fail."<<endl;
  23. }
  24. cout <<"same type? ";
  25. cout << ( typeid(rpolybase)==typeid(*ppolybase) ) << endl;
  26. return 0;
  27. }

执行结果:

原文链接: http://blog.csdn.net/heyabo/article/details/8348624

參考文章:

1.  http://www.cplusplus.com/reference/typeinfo/type_info/
2.  http://en.cppreference.com/w/cpp/language/typeid
3.  http://stackoverflow.com/questions/1986418/typeid-and-typeof-in-c
4.  http://renhl252.blog.163.com/blog/static/2122100720098229281284/

C++ RTTI介绍的更多相关文章

  1. c++之RTTI介绍

    本文介绍c++的RTTI的基本用法,并初步研究RTTI的实现原理. 1. 什么是RTTI RTTI即运行时类型识别(runtime type identification),用于判断指针或引用所绑定对 ...

  2. RTTI

    RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型.   编辑本段RTTI介绍 RTTI提 ...

  3. Delphi 类的类 class of 用法

    http://blog.csdn.net/blue_morning/article/details/8815609 Delphi 类的类 class of 用法   这个概念本来在一个关于Delphi ...

  4. Delphi 类引用 Class Reference 元类 MetaClass 用法

    delphi中类引用的使用实例 类引用类引用(Class Reference)是一种数据类型,有时又称为元类(MetaClass),是类的类型的引用.类引用的定义形式如下: class of type ...

  5. Java系列笔记(2) - Java RTTI和反射机制

    目录 前言 传统的RTTI 反射 反射的实现方式 反射的性能 反射与设计模式 前言 并不是所有的Class都能在编译时明确,因此在某些情况下需要在运行时再发现和确定类型信息(比如:基于构建编程,),这 ...

  6. RTTI (Run-Time Type Identification,通过运行时类型识别) 转

    参考一: RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型.   RTTI提供了以下两个 ...

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

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

  8. C++ RTTI

    一.定义:RTTI:Run Time Type Identification ,运行时类型识别:指程序能够使用基类的指针或引用来检索其所指对象的实际派生类型.二.使用方式:C++中有两个操作符提供RT ...

  9. C++重载(主要介绍使用友元函数重载)

    重载限制 多数C++运算符都可以用下面的方式重载.重载的运算符不必是成员函数,但必须至少有一个操作数是用户自定义的类型.下面详细介绍C++对用户定义的运算符重载的限制. 1 重载后的运算符必须至少有一 ...

随机推荐

  1. Java多线程编程核心技术---Lock的基本概念和使用

    Lock接口: ReentrantLock的基本功能: ReentrantLock的lock和unlock方法进行加锁,解锁.可以起到和synchronized关键字一样的效果: 选择性通知!!!: ...

  2. 未来IT行业的掌控者

    (题外话,我发现很多高手都喜欢讲代码实现,喜欢贴代码贴图,我个人不大喜欢这种方式,我觉得最重要的是思想,是想法,具体的实现代码实现步骤由读者自己去实现.这纯属我个人喜好,望各大内高手勿喷,可能是本人水 ...

  3. 迅为7寸Android嵌入式安卓触摸屏,工业一体机方案

    嵌入式安卓触摸屏板卡介绍-工业级核心板: 嵌入式安卓触摸屏功能接口介绍: 品质保障: 核心板连接器:进口连接器,牢固耐用,国产连接器无法比拟(为保证用户自行设计的产品品质,购买核心板用户可免费赠送底板 ...

  4. Android(java)学习笔记195:ContentProvider使用之添加数据到联系人(掌握)

    1.添加联系人逻辑思路 (1)首先在raw_contacts创建一个新的id (2)在data表里面添加这个id对应的数据 2.下面通过一个案例,说明一下如何添加一条数据到联系人: (1)首先我们关注 ...

  5. 使用VS Code调试Flutter(检查用户页面)

    官方提供的是Flutter Widget Inspector,详见https://flutterchina.club/inspector/ 我用的是另外一种好用的调试工具 Dart DevTools ...

  6. CAD参数绘制椭圆弧(com接口)

    在CAD设计时,需要绘制椭圆弧,用户可以设置椭圆弧基本属性. 主要用到函数说明: _DMxDrawX::DrawEllipseArc 绘制椭圆弧.详细说明如下: 参数 说明 DOUBLE dCente ...

  7. java网络编程_IP地址

    InetAddress类,此类表示Internet协议(IP)地址.具体使用方法查看文档:https://docs.oracle.com/en/java/javase/11/docs/api/java ...

  8. Python 绑定方法与非绑定方法

    用到的: import uuid  --------------  uuid是128位的全局唯一标识符, 通常用32位的一个字符串的形式来表现 uuid.uuid1()  -------------  ...

  9. 又是latch: cache buffers chains惹得祸

    前言 一大早,客户给我打电话说: xx,应用很慢,查询数据总是超时,让我看看... 根据多年DBA经验,首当其冲的肯定是去查询数据库在这段时间都在干嘛. 分析 导出awr报告分析 1). 数据库在此时 ...

  10. 利用WITH AS改写SQL

    报表程序中一段SQL语句. 优化前: 返回:3952 耗时:224s SQL 代码: select to_date(nvl(pro.value, '1900-01-01 00:00:00'), 'YY ...