C++ RTTI介绍

一、定义: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&;
详细定义例如以下:

[cpp] view plaincopyprint?
  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操作符。

样例:(来源[cpp] view plaincopyprint" style="color: rgb(160, 160, 160); text-decoration: none; background-image: none; background-color: inherit; border: none; padding: 0px; margin: 0px 10px 0px 0px; font-size: 9px; background-position: initial initial; background-repeat: initial initial;">?
  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异常。
详细见样例:

[cpp] view plaincopyprint" style="color: rgb(160, 160, 160); text-decoration: none; background-image: none; background-color: inherit; border: none; padding: 0px; margin: 0px 10px 0px 0px; font-size: 9px; background-position: initial initial; background-repeat: initial initial;">?
  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/

时间: 2024-12-10 00:19:37

C++ RTTI介绍的相关文章

32b++ RTTI介绍

http://www.foooooot.com/footprint/3336950/ http://www.foooooot.com/footprint/3336947/ http://www.foooooot.com/footprint/3336945/ http://www.foooooot.com/footprint/3336943/ http://www.foooooot.com/footprint/3336940/ http://www.foooooot.com/footprint/3

RTTI

RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型. 编辑本段RTTI介绍 RTTI提供了以下两个非常有用的操作符: (1)typeid操作符,返回指针和引用所指的实际类型: (2)dynamic_cast操作符,将基类类型的指针或引用安全地转换为派生类型的指针或引用. 面向对象的编程语言,象C++,Java,delphi都提供了对RTTI的支持. 本文将简略介绍 RTTI 的一些背景知

Delphi 类引用 Class Reference 元类 MetaClass 用法

delphi中类引用的使用实例 类引用类引用(Class Reference)是一种数据类型,有时又称为元类(MetaClass),是类的类型的引用.类引用的定义形式如下: class of type 例如: type SomeClass = class of TObject; var AnyObj: SomeClass; TObject = class end; TClass = class of TObject; 下面的例子说明了类引用的用法: program Project1; {$APP

c++中RTTI

RTTI 是"Runtime Type Information"的缩写,意思是:运行时类型信息.它提供了运行时确定对象类型的方法.本文将简略介绍 RTTI 的一些背景知识.描述 RTTI 的概念,并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI:本文还将详细描述两个重要的 RTTI 运算符的使用方法,它们是 typeid 和 dynamic_cast.如何确定对象的动态类型呢?答案是使用内建的 RTTI 中的运算符:typeid 和 dynamic_cast. typeid的

C++的 RTTI 观念和用途(非常详细)

自从1993年Bjarne Stroustrup [注1 ]提出有关C++ 的RTTI功能之建议﹐以及C++的异常处理(exception handling)需要RTTI:最近新推出的C++ 或多或少已提供RTTI. 然而,若不小心使用RTTI,可能会导致软件弹性的降低.本文将介绍RTTI的观念和近况﹐并说明如何善用它. 什么是RTTI﹖      在C++ 环境中﹐头文件(header file) 含有类之定义(class definition)亦即包含有关类的结构资料(representat

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

目录 前言 传统的RTTI 反射 反射的实现方式 反射的性能 反射与设计模式 前言 并不是所有的Class都能在编译时明确,因此在某些情况下需要在运行时再发现和确定类型信息(比如:基于构建编程,),这就是RTTI(Runtime Type Information,运行时类型信息). 在java中,有两种RTTI的方式,一种是传统的,即假设在编译时已经知道了所有的类型:还有一种,是利用反射机制,在运行时再尝试确定类型信息. 本文主要讲反射方式实现的RTTI,建议在阅读本文之前,先了解类的加载机制(

C++ 宏、范型和RTTI 浅析

[摘要] RTTI(Run-Time Type Identification)是面向对象程序设计中一种重要的技术.现行的C++标准对RTTI已经有了明确的支持.不过在某些情况下出于特殊的开发需要,我们需要自己编码来实现.本文介绍了一些关于RTTI的基础知识及其原理和实现,并分析比较三者是线上的差异与联系. [正文] RTTI 的需求 和很多其他语言一样,C++是一种静态类型语言.其数据类型是在编译期就确定的,不能在运行时更改.然而由于面向对象程序设计中多态性的要求,C++中的指针或引用(Refe

RTTI技术

在C++中通过虚函数,模板编程和RTTI技术可以实现多态.关于虚函数和模板编程不再赘述,下面来介绍RTTI技术. 所谓RTTI技术,是Run Time Type Infomation的缩写,即运行时类型信息.它提供了运行时确定对象类型的方法.对于大多数人而言,可能都不知道在C++中还有RTTI.其实在C++编程中有时候不可避免地需要对对象类型进行动态判断,那么如何确定对象的动态类型呢? 答案就是使用C++内置的RTTI运算符typeid和dynamic_cast. 详细参考:http://blo

Delphi 的RTTI机制浅探&lt;二&gt;

目 录===============================================================================⊙ GetTypeData 函数⊙ GetPropInfo 函数⊙ FindPropInfo 函数⊙ GetPropInfos 函数⊙ SortPropList 函数⊙ GetPropList 函数------------------------------------------------------⊙ GetObjectProp