运行时类型识别(Run-time type identification , RTTI),是指在只有一个指向基类的指针或引用时,确定所指对象的准确类型的操作。其常被说成是C++的四大扩展之一(其他三个为异常、模板和名字空间)。

使用RTTI的两种方法:

  1、typeid()

  第一种就像sizeof(),它看上像一个函数,但实际上它是由编译器实现的。typeid()带有一个参数,它可以是一个对象引用或指针,返回全局typeinfo类的常量对象的一个引用。可以用运算符“= =”和“!=”来互相比较这些对象,也可以用name()来获得类型的名称。如果想知道一个指针所指对象的精确类型,我们必须逆向引用这个指针。比如:

#include <typeinfo>
#include <iostream>
#include <cmath>
using namespace std;
class Shape
{
public :
int area(float r)
{
float s=3.14*pow(r,);
return s;
}
};
int main()
{
Shape* shape=new Shape;
cout<< typeid(*shape).name()<<endl;
system("pause");
}

  运行结果为:

  为了保持一致性,typeid()也可以用于内部类型,所以下面的表达式结果为true:

typeid(36) == typeid(int)
typeid() == typeid(int) int i;
typeid(i) == typeid(int)
typeid(&i) ==typeid(int*)

  可以用typeid 检查基本类型和非多态类型

//可以用typeid 检查基本类型和非多态类型:
#include <typeinfo>
#include <iostream>
using namespace std;
typedef unsigned int UINT ;
int main()
{
cout<< typeid(UINT).name()<<endl;
cout<< typeid(string).name()<<endl;
system("pause");
}

  运行结果如图所示:

  用typeid分析指针与引用的区别

#include <typeinfo>
#include <iostream>
using namespace std;
class B
{
public:
virtual double fun()
{
return 0.1;
}
};
class D :public B
{
};
int main()
{
B *p = new D;
B &r = *p; //无名对象照样有别名
cout<<(typeid(p)==typeid(B*)); //仅指向子类中父类部分
cout<<(typeid(p)!=typeid(D*)); //而非指向整个子类对象
cout<<(typeid(r)==typeid(D)); //引用的类型却是子类的
cout<<(typeid(*p)==typeid(D)); //间址访问的是子类对象
cout<<(typeid(*p)!=typeid(B)); //而非父类
cout<<(typeid(&r)==typeid(B*)); //引用的地址是父类的
cout<<(typeid(&r)!=typeid(D*)); //而非子类的
system("pause");
return ;
}

  运行结果:

  2、dynamic_cast <type-id> (expression)

  该运算符把expression转换成type-id类型的对象。Type-id 必须是类的指针、类的引用或者void*,不可是对象;如果 type-id 是类指针类型,那么expression也必须是一个指针,如果 type-id 是一个引用,那么 expression 也必须是一个引用。
  dynamic_cast主要用于类层次间的上行转换下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_caststatic_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
#include <typeinfo>
#include <iostream>
using namespace std;
class Shape
{
public:
virtual void Draw()
{
}
};
class Circle:public Shape
{
public:
virtual void Draw()
{
}
};
int main()
{
Shape* sp=new Circle;
Circle* cp=dynamic_cast<Circle*>(sp);
if(cp)
cout<<"cast successful"<<endl;;
system("pause");
}

  运行结果:

如何使用RTTI:

  • 先激活RTTI;
  • 对象所属类型必须是多态类族
  • 若使用dynamic_cast<>转换一个引用,则要使用异常处理机制,因为它可能抛出 std::bad_cast异常;当使用dynamic_cast<>运算符转换一个指针时,定要检查结果是否为NULL
  • 若使用typeid (*p)来检索对象的类型信息,又恰碰 p == NULL时,将抛出std::bad_typeid异常;

RTTI(运行时类型识别)的更多相关文章

  1. RTTI 运行时类型识别 及异常处理

    RTTI   运行时类型识别 typeid  ------  dynamic_cast dynamic_cast 注意事项: 1.只能应用于指针和引用之间的转化 2.要转换的类型中必须包含虚函数 3. ...

  2. 框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解)

    框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解) 一丶什么是RTTI,以及RTTI怎么设计 通过第一讲,我们知道了怎么样升成一个窗口了,以及简单的消息循环. 第二讲则是主要讲解RTTI ...

  3. MFC原理第三讲.RTTI运行时类型识别

    MFC原理第三讲.RTTI运行时类型识别 一丶什么是RTTI RTTI. 运行时的时候类型的识别. 运行时类型信息程序.能够使用基类(父类)指针 或者引用 来检查这些指针或者引用所指的对象. 实际派生 ...

  4. Java基础之RTTI 运行时类型识别

    运行时类型识别(RTTI, Run-Time Type Identification)是Java中非常有用的机制,在Java运行时,RTTI维护类的相关信息. 多态(polymorphism)是基于R ...

  5. RTTI(运行时类型识别)

    C++为了能够在运行时正确判断一个对象确切的类型,加入了RTTI和type_info. type_info 为每一个类型增加一个type_info对象. 为了能够在运行时获得对象的类型信息type_i ...

  6. RTTI(运行时类型识别),typeid,dynamic_cast

    dynamic_cast注意: 1.只能应用于指针和引用的转换: 2.要转换的类型中必须包含虚函数: 3.转换成功则返回地址,如果失败则返回NULL: 参见项目:RTTI

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

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

  8. MFC六大核心机制之二:运行时类型识别(RTTI)

    上一节讲的是MFC六大核心机制之一:MFC程序的初始化,本节继续讲解MFC六大核心机制之二:运行时类型识别(RTTI). typeid运算子 运行时类型识别(RTTI)即是程序执行过程中知道某个对象属 ...

  9. C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理

    运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. ...

随机推荐

  1. Makefile编写参考

    http://www.ruanyifeng.com/blog/2015/02/make.html

  2. JS拖拽元素原理及实现代码

    一.拖拽的流程动作 ①鼠标按下②鼠标移动③鼠标松开 二.拖拽流程中对应的JS事件 ①鼠标按下会触发onmousedown事件 ②鼠标移动会触发onmousemove事件 ③鼠标松开会触发onmouse ...

  3. get请求中url传参中文乱码问题--集锦

    一:get请求url中带有中文参数,有三种方式进行处理防止中文乱码 1.如果使用tomcat作为服务器,那么修改tomcat配置文件conf/server.xml中,在  <Connector  ...

  4. iptables禁止别人,允许自己

    这里举个例子,以ping为案例:禁止别人ping自己,但允许自己ping别人. [root@localhost ~]# iptables -A INPUT -p icmp --icmp-type 8 ...

  5. windows 查询端口占用 杀掉进程

    参考 https://www.cnblogs.com/lynn-li/p/6077993.html netstat -ano | findstr "8001" taskkill / ...

  6. 第十一章 串 (c3)KMP算法:理解next[]表

  7. 使用FFMPEG类库分离出多媒体文件中的H.264码流

    在使用FFMPEG的类库进行编程的过程中,可以直接输出解复用之后的的视频数据码流.只需要在每次调用av_read_frame()之后将得到的视频的AVPacket存为本地文件即可. 经试验,在分离MP ...

  8. Linux系统一本通(实用篇)

    本人最近一直在ubuntu,接下来和大家分享我曾经踩过的坑,和一些非常实用的命令知识- 安装中的磁盘分配 一般来说,在linux系统中都有最少两个挂载点,分别是/ (根目录)及 swap(交换分区), ...

  9. PHP连接数据库(mysql)

    前端链接后台,数据库几乎必不可少.所以本文总结了PHP链接数据库的常用方法步骤. 首先 链接数据库:mysqli_connect参数①主机地址 ②mysql用户名③nysql密码④选择连接的数据库⑤端 ...

  10. AngulairJS表单输入验证与mvc

    AngulairJS表单输入验证 1.表单中,常用的验证操作有:$dirty 表单有填写记录.$valid 字段内容合法的.$invalid 字段内容是非法的.$pristine 表单没有填写记录.$ ...