一、定义: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. 观锁和乐观锁——《POJOs in Action》

    1        事务隔离 事务隔离是数据库提供的功能. SQL Server通过SET TRANSACTION ISOLATION LEVEL语句设置事务隔离级别: SET TRANSACTION ...

  2. (转)淘淘商城系列——SSM框架整合之逆向工程

    http://blog.csdn.net/yerenyuan_pku/article/details/72758590 我们知道在开发中有些工作是非常耗时但是又没有什么技术含量的,比如创建mapper ...

  3. pom.xml配置引用项目时不生效

    1 在项目pom.xml配置中引用项目A,但是编译时,取提数引起是B: 2 原因是:[Java Build Path - Projects] 引用的还是老的项目B,删除该引用即可解决.

  4. python 2 encode and decode

    https://docs.python.org/2/howto/unicode.html a Unicode string is a sequence of code points, which ar ...

  5. UIWebView中javascript与Objective-C交互、获取摄像头

    UIWebView是iOS开发中常用的一个视图控件,多数情况下,它被用来显示HTML格式的内容. 支持的文档格式 除了HTML以外,UIWebView还支持iWork, Office等文档格式: Ex ...

  6. [Algorithm] 2. Trailing Zeros

    Description Write an algorithm which computes the number of trailing zeros in n factorial. Example 1 ...

  7. [Python3网络爬虫开发实战] 1.9.3-Scrapyd-Client的安装

    在将Scrapy代码部署到远程Scrapyd的时候,第一步就是要将代码打包为EGG文件,其次需要将EGG文件上传到远程主机.这个过程如果用程序来实现,也是完全可以的,但是我们并不需要做这些工作,因为S ...

  8. MYSQL有那些优化?

    版权声明:本文为博主转载文章,原博主地址: https://blog.csdn.net/u013087513/article/details/77899412 MySQL优化三大方向 ① 优化MySQ ...

  9. Python面试快问快答,理论要的就是速度与精准,Python面试题No2

    今天的面试题 第1题:python2和python3的range(100)的区别 range()函数的含义 range函数是一个用来创建算数级数序列的通用函数,返回一个[start, start + ...

  10. 建仓类型与对应建仓价MT4

    建仓类型与对应建仓价 (Bid,Ask) 建仓类型 对应建仓价 Buy Ask+Spread Sell Bid-Spread BuyLimit Ask-Spread-StopLevel SellLim ...