0

0

C++里的typeid和RTTI是什么?(运行时类型识别与动态类型检查)

冰火之心

冰火之心

发布时间:2026-01-09 14:42:43

|

144人浏览过

|

来源于php中文网

原创

typeid用于运行时类型查询,返回std::type_info引用;限制包括:仅多态类型支持动态类型识别、需启用RTTI、空指针解引用抛bad_typeid、跨编译单元比较不可靠、对数组/引用/CV限定符敏感。

c++里的typeid和rtti是什么?(运行时类型识别与动态类型检查)

typeid 在 C++ 里怎么用,有哪些限制

typeid 是 C++ 提供的运行时类型查询操作符,返回一个 std::type_info 引用,可用于获取对象或类型的静态/动态类型信息。但它不是万能的:对非多态类型(即不含虚函数的类),typeid 返回的是**编译期类型**,而非实际对象类型。

  • 必须开启 RTTI 支持(大多数编译器默认开启;GCC/Clang 用 -frtti,MSVC 默认启用)
  • 对空指针调用 typeid(*ptr) 会抛出 std::bad_typeid 异常
  • typeid 不支持比较不同编译单元中定义的同名类(因 type_info::name() 可能不一致,且 operator== 的行为依赖实现)
  • 对数组、引用、cv 限定符敏感:typeid(int[3])typeid(const int&) 都产生独立的 type_info

RTTI 开启后,dynamic_cast 为什么比 static_cast 更安全

RTTI 的核心价值之一是支撑 dynamic_cast 的安全向下转型。它只对**多态类型**(含至少一个虚函数)生效,并在运行时检查继承关系是否成立。失败时,对指针返回 nullptr,对引用抛出 std::bad_cast

  • static_cast 在编译期完成转换,不验证实际对象类型,误转会导致未定义行为
  • dynamic_cast 要求源类型必须是多态的;否则编译报错:error: cannot dynamic_cast ... which is not a polymorphic type
  • 多重继承下,dynamic_cast 还能正确调整 this 指针偏移,static_cast 无法保证这点
  • 性能开销存在:每次调用需查虚表中的 type_info 指针并做比较,但现代编译器对单继承有优化

如何判断一个类型是否支持 RTTI(即是否多态)

不能靠 typeiddynamic_cast 是否“报错”来探测——它们的行为依赖编译选项和类型结构。最可靠的方式是在编译期用类型特征:

static_assert(std::is_polymorphic_v, "MyClass must be polymorphic for RTTI use");
  • std::is_polymorphic_v 中定义,返回 true 当且仅当 T 有虚函数(包括虚析构)
  • 注意:空基类、POD 类型、无虚函数的派生类都不满足该条件
  • 即使开启了 RTTI,对非多态类型使用 dynamic_cast 仍非法;而 typeid 虽可用,但结果与 static_cast 等效,无动态意义

常见 RTTI 相关错误和调试建议

RTTI 问题往往表现为静默错误或崩溃,而不是编译失败。典型现象包括:

CreBee
CreBee

短视频矩阵运营工具,跨平台多账号一站式管理

下载

立即学习C++免费学习笔记(深入)”;

  • dynamic_cast 转换非多态类型 → 编译失败,看清错误信息里的 “not a polymorphic type”
  • 对 null 指针解引用后 typeid → 抛 std::bad_typeid,应先判空
  • 跨 DLL/so 边界传递对象并 typeid 比较 → type_info::operator== 可能返回 false,即使名字相同;避免跨模块直接比较 type_info,改用字符串名(但注意 name() 无标准格式)
  • 关闭 RTTI(如 GCC 加 -fno-rtti)后仍用了 dynamic_casttypeid → 链接失败或编译报错,错误提示通常明确

真正麻烦的是误以为 typeid 能替代接口设计:比如用一长串 if (typeid(obj) == typeid(A)) {...} else if (typeid(obj) == typeid(B))...。这不仅脆弱、难维护,还绕过了虚函数机制本应提供的扩展性。遇到这种代码,优先考虑重构为访问者模式或 std::variant(C++17)。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

435

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

723

2023.08.22

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

187

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

271

2023.10.25

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

520

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

253

2023.08.03

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

3

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号