RTTI(Run-Time Type Information,通过运行时类型信息)程序能够使用基类指针或引用来检查这些指针或引用所指的对象的实际派生类型.

RTTI提供了以下两个非常有用的操作符:
(1)typeid操作符,返回指针和引用所指的实际类型。
(2)dynamic_cast操作符,将基类类型的指针或引用安全地转换为派生类型的指针或引用。
 面向对象的编程语言,象C++,Java,delphi都提供了对RTTI的支持。 本文将简略介绍 RTTI 的一些背景知识、描述 RTTI 的概念,并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI;本文还将详细描述两个重要的 RTTI 运算符的使用方法,它们是 typeid 和dynamic_cast。
其实,RTTI 在C++中并不是什么新的东西,它早在十多年以前就已经出现了。但是大多数开发人员,包括许多高层次的C++程序员对它并不怎么熟悉,更不用说使用 RTTI 来设计和编写应用程序了。
 
   一些面向对象专家在传播自己的设计理念时,大多都主张在设计和开发中明智地使用虚拟成员函数,而不用 RTTI 机制。但是,在很多情况下,虚拟函数无法克服本身的局限。每每涉及到处理异类容器和根基类层次(如 MFC)时,不可避免要对对象类型进行动态判断,也就是动态类型的侦测。如何确定对象的动态类型呢?答案是使用内建的 RTTI 中的运算符:typeid 和 dynamic_cast。
 
   在C++中存在虚函数,也就存在了多态性,对于多态性的对象,在程序编译时可能会出现无法确定对象的类型的情况。当类中含有虚函数时,其基类的指针就可以指向任何派生类的对象,这时就有可能不知道基类指针到底指向的是哪个对象的情况,类型的确定要在运行时利用运行时类型标识做出。为了获得一个对象的类型可以使用typeid函数,该函数反回一个对type_info类对象的引用,要使用typeid必须使用头文件<typeinfo>,因为typeid是一个返回类型为typ_info的引用的函数所以这里有必要先介绍一下type_info类.

typeid函数

该函数的主要作用就是让用户知道当前的变量是什么类型的,比如使用typeid(a).name()就能知道变量a是什么类型的。因为typeid()函数是一个返回类型为const typeid_info&类型的函数,所以下面先对type_info类作下介绍

type_info类

该类的具体实现方式依编译器而定,但一般都有如下的成员定义
classtype_info
{
private:
type_info(consttype_info&);
type_info&operator=(consttype_info&);//type_info类的复制构造函数和赋值运算符是私有的。
public:
virtual~type_info();//析构函数
booloperator==(consttype_info&)const;//在type_info类中重载了==运算符,该运算符可以比较两个对象的类型是否相等。
booloperator!=(consttype_info&)const;//重载的!=运算符,以比较两个对象的类型是否不相等
constchar*name()const;//使用得较多的成员函数name,该函数反回对象的类型的名字。前面使用的typeid(a).name()就调用了该成员函数
boolbefore(consttype_info&);
};
因为type_info类的复制构造函数和赋值运算符都是私有的,所以不允许用户自已创建type_info的对象,比如type_info A;错误,没有默认的构造函数。唯一要使用type_info类的方法就是使用typeid函数。

typeid函数怎样创建type_info类的对象

该函数返回type_info类对象的引用,即形式为const type_info& typeid();因此也可以说typeid函数是type_info类的一个引用对象,可以访问type_info类的成员。但因为不能创建type_info类的对象,而typeid又必须返回一个类型为type_info类型的对象的引用,所以怎样在typeid函数中创建一个type_info类的对象以便让函数返回type_info类对象的引用就成了问题。这可能是把typid函数声明为了type_info类的友元函数来实现的,默认构造函数是私有的并不能阻止该类的友元函数创建该类的对象。所以typeid函数如果是友元的话就可以访问type_info类的私有成员,从而可以创建type_info类的对象,从而可以创建反回类型为type_info类的引用。
举个例子:
class A{private:A(){} A(const A&){} A& operator =(const A&){} friend A& f();};这里把类A的默认构造函数,复制构造函数和赋值操作符定为私有从而防止创建类A的对象,但函数f()是类A的友元,所以在函数f()中可以创建类A的对象。同时为了实现函数f()返回的对象类型是A的引用,就必须在函数f中创建一个类A的对象以作为函数f的返回值,比如函数f可以这样定义A& f(){A ma; cout<<”f”<<endl; return ma}。
(个人解:A ma是局部对象,函数运行完后会释放掉,不能返回ma,这里好像有错误。)
 
因为typeid函数是type_info类的对象,也就是说可以用该函数访问type_info类的成员,即type_info类中重载的= =和!=运算符,name()和before()成员函数,比如typid(a).name()和typid(a) == typid(b)等等。
 
// expre_typeid_Operator.cpp
// compile with: /GR /EHsc
#include <iostream>
#include <typeinfo.h> class Base
{
public:
virtual void vvfunc() {}
}; class Derived : public Base {}; using namespace std; int main()
{
Derived* pd = new Derived;
Base* pb = pd;
int i = ; cout << typeid( i ).name() << endl; // prints "int"
cout << typeid( 3.14 ).name() << endl; // prints "double"
cout << typeid( pb ).name() << endl; // prints "class Base *"
cout << typeid( *pb ).name() << endl; // prints "class Derived"
cout << typeid( pd ).name() << endl; // prints "class Derived *"
cout << typeid( *pd ).name() << endl; // prints "class Derived" delete pd;
}

typeid最常见的用途是比较两个表达式的类型,或者将表达式的类型与特定类型相比较。

Base *bp;
Derived *dp;
// compare type at run time of two objects
if (typeid(*bp) == typeid(*dp))
{
// bp and dp point to objects of the same type
}
// test whether run time type is a specific type
if (typeid(*bp) == typeid(Derived))
{
// bp actually points a Derived
}

注意:如果是typeid(bp),则是对指针进行测试,这会返回指针(bp)的静态编译时类型(Base *)。

如果指针p的值是0,,并且指针所指的类型是带虚函数的类型,则typeid(*p)抛出一个bad_typeid异常。

参考:http://baike.baidu.com/view/1042388.htm

更多:

http://blog.csdn.net/acdnjjjdjkdckjj/article/details/6326189

http://dxwang.blog.51cto.com/384651/79036
http://blog.csdn.net/yueguanghaidao/article/details/7935960

c++ RTTI(runtime type info)的更多相关文章

  1. C++ - RTTI(RunTime Type Information)执行时类型信息 具体解释

    RTTI(RunTime Type Information)执行时类型信息 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details ...

  2. RTTI (Run-time type information) in C++

    In C++, RTTI (Run-time type information) is available only for the classes which have at least one v ...

  3. c++对象模型和RTTI(runtime type information)

    在前面已经探讨过了虚继承对类的大小的影响,这次来加上虚函数和虚继承对类的大小的影响. 先来回顾一下之前例子的代码: #include <iostream> using namespace ...

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

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

  5. RTTI(Runtime Type Information )

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

  6. Dynamic type checking and runtime type information

    动态类型的关键是将动态对象与实际类型信息绑定. See also: Dynamic programming language and Interpreted language Dynamic type ...

  7. Run-time type information--RTTI

    In computer programming, run-time type information or run-time type identification (RTTI)[1] refers ...

  8. Java RTTI机制与反射机制

    1.1 什么是RTTI? 维基百科的定义:In computer programming, RTTI (Run-Time Type Information, or Run-Time Type Iden ...

  9. java之RTTI和反射的理解

    最近在读 Thinking in Java 这本书.读到类型信息这一张时,刚开始对书中所说的RTTI和反射彻底混了,不知道有什么联系,有哪些相同点和区别.于是在网上又找了些内容辅助理解,这一章又重新读 ...

随机推荐

  1. ZeroClipboard.swf

    ZeroClipboard.config({             moviePath: "source/ZeroClipboard.swf",             hove ...

  2. Google Map API v2 (三)----- 地图上添加标记(Marker),标记info窗口,即指定经纬度获取地址字符串

    接上篇 http://www.cnblogs.com/inkheart0124/p/3536322.html 1,在地图上打个标记 private MarkerOptions mMarkOption; ...

  3. ASP.NET获取汉字首字母

    /// <summary> /// 获取汉字首字母(可包含多个汉字) /// </summary> /// <param name="strText" ...

  4. eclipse同时开两个tomcat

    首先设置环境变量: 接着修改其中一个tomcat下bin文件夹的startup.bat和catalina.bat 将里面所有CATALINA_HOME都修改为CATALINA_HOME2 然后 修改c ...

  5. PHP解决多进程同时读写一个…

    原文地址:PHP解决多进程同时读写一个文件的问题作者:陌上花开 首先PHP是支持进程的而不支持多线程(这个先搞清楚了),如果是对于文件操作,其实你只需要给文件加锁就能解决,不需要其它操作,PHP的fl ...

  6. 认识javascript作用域

    JavaScript的作用域链 这是一个非常重要的知识点了,了解了JavaScript的作用域链的话,能帮助我们理解很多‘异常’问题. 下面我们来看一个小例子,前面我说过的声明提前的例子. var n ...

  7. enableEventValidation

    回发或回调参数无效.在配置中使用 <pages enableEventValidation="true"/> 或在页面中使用 <%@ Page EnableEve ...

  8. python查看网站的RTT

    import requests time=0.0 jpserver=['jp1.herejump.com','jp1.herejump.com','jp1.herejump.com'] usserve ...

  9. Android SQLite ORM框架greenDAO在Android Studio中的配置与使用

    博客: 安卓之家 微博: 追风917 CSDN: 蒋朋的家 简书: 追风917 博客园: 追风917 # 说明 greenDAO是安卓中处理SQLite数据库的一个开源的库,详情见其官网:我是官网 详 ...

  10. Oracel JDBC URL 和 Driver 的获取

    Driver 的获取 Driver Name:   oracle.jdbc.driver.OracleDriver Oracel JDBC URL的获取: URL:   jdbc:oracle:thi ...