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. iOS UIKit:animation

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...

  2. CentOS 6.7 安装配置BT下载工具Transmission

    1.配置额外yum源 i386 cd /etc/yum.repos.d/ wget http://geekery.altervista.org/geekery-el6-i686.repo x86_64 ...

  3. Effective C++ 笔记二 构造/析构/赋值运算

    条款05:了解C++默默编写并调用哪些函数 编译器默认声明一个default构造函数.一个copy构造函数.一个copy assignment操作符和一个析构函数.这些函数都是public且inlin ...

  4. 30、ADO.NET、事务、DataSet

    ADO.NET ADO.NET是一组用于和数据源进行交互的面向对象类库.通常数据源是数据库,但也可以是文本文件.Excel表格.XML文件. 说白了就是使用.net操作数据库的一套类库. ADO.NE ...

  5. 我对WindowsPhone8的一些反大众看法.

    最近看到网上好多人抱怨wp8的系统设计.我个人有一些观点.实在是不吐不快! 1.为什么系统没有重力感应开关.   答:因为这部分开关功能不是wp8所必备的.只是APP的一个功能.所以.错误在APP上因 ...

  6. java: Eclipse jsp tomcat 环境搭建(完整)

    ] 欢迎您! 要学习一门语言,首先要做的就是搭建环境,然后能写一个小的Demo(类似Helloworld),不仅可以建立信心,而且还可以为之后的学习搭建一个验证平台,事半功倍. net领域的vs,号称 ...

  7. oracle sql语句

    一.ORACLE的启动和关闭1.在单机环境下要想启动或关闭ORACLE系统必须首先切换到ORACLE用户,如下su - oracle a.启动ORACLE系统oracle>svrmgrlSVRM ...

  8. ORACLE如何停止一个JOB

    ORACLE如何停止一个JOB1 相关表.视图2 问题描述为同事解决一个因为网络连接情况不佳时,执行一个超长时间的SQL插入操作.既然网络状况不好,就选择了使用一次性使用JOB来完成该插入操作.在JO ...

  9. UIScrollView -2(UIScrollView 与 UIPageControl的使用): 分页查看图片

    1.初始化UIScrollView 2.设置初始化出来的UIScrollView的contentSize: myscrollview.contentSize =CGSizeMake(CGRectGet ...

  10. ios专题 - 单例模式的实现

    [原创]http://www.cnblogs.com/luoguoqiang1985 单例模式是什么? 一个类只有一个实例. ----------------------- 这样做有什么好处? 在我的 ...