一、定义: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. [Windows Server 2012] MySQL移机方法

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:MySQL ...

  2. vba,excel,身份证,照片

    Sub 插入图片() '调整单元格大小,以适应图片大小 功能 插入身份证照片打印 - 正面在单元格d6       反面单元格d10 ActiveSheet.Pictures.Delete '清理过期 ...

  3. 语音行业技术领先者Nuance上海诚招ASR/NLP研发工程师和软件工程师

    Nuance is a leading provider of voice and language solutions for businesses and consumers around the ...

  4. Bootstrap modal使用及点击外部不消失的解决方法

    这篇文章主要为大家详细介绍了Bootstrap modal使用及点击外部不消失的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了Bootstrap modal使用及点击 ...

  5. 迅速搞懂JavaScript正则表达式之方法

    咱们来看看JavaScript中都有哪些操作正则的方法. RegExp RegExp 是正则表达式的构造函数. 使用构造函数创建正则表达式有多种写法: new RegExp('abc');// /ab ...

  6. create_module - 生成一条可加载模块记录

    总览 #include <linux/module.h> caddr_t create_module(const char *name, size_t size); 描述 create_m ...

  7. git 提交运用vim编辑器

    git  commit -m 默认使用nano,觉得不爽,改成vim吧.在 .gitconfig (在根目录下)的  [core] 段中加上 editor=vim . 或:$git config -- ...

  8. h5开发app,移动端 click 事件响应缓慢的解决方案

    造成点击缓慢的原因 从点击屏幕上的元素到触发元素的 click 事件,移动浏览器会有大约 300 毫秒的等待时间.为什么这么设计呢? 因为它想看看你是不是要进行双击(double tap)操作. 使用 ...

  9. JAVA基础——IO流字符流

    字符流 字节流提供了处理任何类型输入/输出操作的功能(因为对于计算机而言,一切都是0和1,只需把数据以字节形式表示就够了),但它们不可以直接操作Unicode字符,因为上一篇文章写了,一个Unicod ...

  10. swiper 旋转木马效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...