C++ RTTI简介

RTTI简介

RTTI(Runtime Type Identification)是"运行时类型识别"的意思。C++是一门静态类型语言,其数据类型是在编译期就确定的,不能在运行时更改。然而由于面向对象程序设计中多态性的要求,C++中的指针或引用本身的类型,可能与它实际代表的类型并不一致,有时我们需要将一个多态指针转换为其实际指向对象的类型,就需要知道运行时的类型信息,这就有了运行时类型识别需求。和Java相比,C++要想获得运行时类型信息,只能通过RTTI机制,并且C++最终生成的代码是直接与机器相关的。

C++通过以下两个关键字提供RTTI功能:

  1. typeid:该运算符返回其表达式或类型名的实际类型
  2. dynamic_cast:该运算符将基类的指针或引用安全地转换为派生类类型的指针或引用(也就是所谓的下行转换)

typeid

静态

当typeid中的操作数是以下任意一种时,typeid得出的是静态类型,即编译时就确定的类型:

  • 一个任意的类型名
  • 一个基本内置类型的变量,或指向基本内置类型的指针或引用
  • 一个任意类型的指针(指针就是指针,本身不体现多态,多指针解引用才有可能会体现多态)
  • 一个具体的对象实例,无论对应的类有没有多态都可以直接在编译器确定
  • 一个指向没有多态的类对象的指针的解引用
  • 一个指向没有多态的类对象的引用

动态

当typeid中的操作数是以下任意一种时,typeid需要在程序运行时推算类型,因为其操作数的类型在编译时期是不能被确定的:

  • 一个指向含有多态的类对象的指针的解引用
  • 一个指向含有多态的类对象的引用

dynamic_cast

这是最常用的RTTI组件,它不能回答"指针指向的是哪类对象"这样的问题,但能够回答"是否可以安全地将对象的地址赋给特定类型的指针"这样的问题。

说白了,就是看看这个对象指针能不能转换为目标指针。

通常,如果指向的对象(*pt)的类型为Type或者是从Type直接或简介派生而来的类型,则下面的表达式将指针pt转换为Type类型的指针:

cpp 复制代码
dynamic_cast<Type *>(pt)

否则,结果为0,即空指针。

注意:即使编译器支持RTTI,在默认情况下,它也可能关闭该特性。如果该特性被关闭,程序可能仍能够通过编译,但将出现运行阶段错误。在这种情况下,应该查看文档或菜单选项。

也可以将dynamic_cast用于引用,用法稍微有点不同:

没有与空指针对应的引用值,因此无法使用特殊的引用值来指示失败。当请求不正确时,dynamic_cast将引发类型为bad_cast的异常,这种异常是从exception类派生而来的,它是在头文件typeinfo中定义的。

C++ RTTI详解

【C++】RTTI有什么用?怎么用? - 知乎 (zhihu.com)

相关推荐
weixin_460443563 小时前
2026年新修订《网络安全法》实施:Java私有化考试系统如何做好SBOM、漏洞治理与安全升级?
java·开发语言·在线考试系统·企业培训考试系统·宏远培训考试系统·国企培训考试系统·国产化培训系统
海鸥-w6 小时前
什么是AOP
java
Cc.Y6 小时前
Java零基础入门:可变字符串与包装类:StringBuilder、StringBuffer 与 通讯录管理系统实战
java·开发语言·python
paopaokaka_luck6 小时前
基于springboot+vue的智慧家政管理系统(AI问答、 WebSocket实时沟通、ECharts运营分析、订单规则与服务追踪)
java·javascript·spring boot·数据分析·echarts·mybatis
sm_926787056 小时前
RFID 标签打印的技术实现要点与二次开发实践
java·大数据·前端·c++·编辑器
阿森_dev6 小时前
2027 届毕设选题怎么选:30 个 Java 方向选题的实现难度排序
java·开发语言·spring boot·毕业设计·课程设计
by209996 小时前
C++ 多态:同一个基类接口,调用不同的函数
开发语言·c++·经验分享·多态
Sarvartha6 小时前
Lambda 表达式和函数式接口
java·开发语言
计算机毕业设计杰瑞7 小时前
【计算机毕设精品】基于SpringBoot的一体化教务与学业质量管理系统的设计与实现,附源码_增删改查_java项目_可完美运行部署_网站项目
java·spring boot·课程设计
colinu7 小时前
C++ 异步任务与线程生命周期:`std::async`、`future`、`thread`、`jthread` 与协作式退出
java·jvm·c++