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. nodejs 中koa框架下的微信公众号开发初始篇

    最近在搞微信公众号开发,后端采用的是nodejs下的koa框架,初识后端的菜鸟,自己搞难度太大了,网上找了很多文章,采用的中间件大都是express框架下的,不过好在爬了许多坑之后总算看见点曙光了,遂 ...

  2. Spring整合CXF步骤,Spring实现webService,spring整合WebService

    Spring整合CXF步骤 Spring实现webService, spring整合WebService >>>>>>>>>>>> ...

  3. git使用备忘

    简单的记录下现在使用git的时候,暂时或者常用到的命令,纯粹自己备忘,没用到过的命令就不写了,日后有用到了在补充. 1.把远程仓库克隆到本地:git clone 远程地址 2.分支操作 新建分支:gi ...

  4. sql if

    SELECT a.id, a.EduSiteNo, a.EduSiteName, a.SchoolId, a.LinkMan, a.Tel, a.Mobile, a.Fax, a.Address, C ...

  5. ASP.NET MVC ajax提交 防止CSRF攻击

    //在View中 <script type="text/javascript"> @functions{ public string ToKenHeaderValue( ...

  6. JOSN学习总结<二> JSON的格式与语法

    今晚又下班早!!嘿嘿,继续JOSN的总结吧!!!!有人说这么简单还有必要写吗???我觉得“眼里过十遍不如手里过一遍”!!有错误之处请指正!!共同学习下!!!!废话不说了,进入今晚的正题: <二& ...

  7. spring security 11种过滤器介绍

    1.HttpSessionContextIntegrationFilter 位于过滤器顶端,第一个起作用的过滤器. 用途一,在执行其他过滤器之前,率先判断用户的session中是否已经存在一个Secu ...

  8. bootstap 滚动监听

    ---首先结合源代码介绍官网的说明 ---然后总结了使用滚动监听的几个步骤 ---最后给出一个简单的例子 ---关键的一点:整体有点零散和乱七八糟,辛苦你的思维和眼睛了,呵呵 ------------ ...

  9. (转)php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法

    php 获取今日.昨日.上周.本月的起始时间戳和结束时间戳的方法,主要使用到了 php 的时间函数 mktime. 下面首先还是直奔主题以示例说明如何使用 mktime 获取今日.昨日.上周.本月的起 ...

  10. Binary Tree Inorder Traversal 解题思路 ×

    问题: 非递归中序遍历二叉树 思路: 1.大循环,判断节点是否为空,栈是否为空 2.不为空:点进栈,向左走 3.为空:为空,出栈,读取值,向右走