0

0

C++中的RTTI(运行时类型识别)是什么?(如何通过typeid获取类名)

穿越時空

穿越時空

发布时间:2026-02-26 00:03:16

|

116人浏览过

|

来源于php中文网

原创

typeid::name() 返回乱码因编译器实现定义,gcc/clang 返回 mangled 名,需 demangle;判断多态类型须确保对象为虚函数类的引用/指针;模板中用 typeid 易触发 odr 违规,应避免;禁用 rtti 后 typeid 和 dynamic_cast 直接编译失败。

c++中的rtti(运行时类型识别)是什么?(如何通过typeid获取类名)

typeid 返回的 type_info::name() 为什么总是乱码或缩写?

因为 type_info::name() 的返回值是编译器实现定义的,不保证可读——GCC/Clang 返回的是经过 ABI mangling 的符号名(比如 "N5mylib7WidgetE"),MSVC 虽稍友好但仍有缩写(如 "class mylib::Widget")。这不是 bug,是标准允许的行为。

  • 想看人能读懂的类名,必须调用 abi::__cxa_demangle()(GCC/Clang)或 UnDecorateSymbolName()(MSVC)做反解
  • 注意:demangle 是非标准 C++,需链接 libstdc++libc++,且返回的内存需手动 free()
  • 调试时直接用 IDE 的“Evaluate Expression”或 GDB 的 ptype 更可靠,别依赖 name() 输出做日志

如何安全地用 typeid 判断多态对象的真实类型?

必须确保目标对象指针/引用指向的是**多态类型**(即至少有一个 virtual 函数),否则 typeid 在表达式求值时只返回静态类型,不是运行时类型。

  • 错误写法:Base b; typeid(b) → 永远返回 Base,哪怕 b 实际是 Derived 对象(切片已发生)
  • 正确前提:用 Base&Base* 指向 Derived 实例,且 Base 有虚函数(哪怕只有虚析构)
  • 推荐替代方案:优先用 dynamic_cast 做类型安全转换,比反复比对 typeid 更符合意图

typeid 在模板里怎么用才不会意外触发 ODR-violation?

当在头文件中对同一类型多次取 typeid(尤其在内联函数或模板实例化中),可能违反“一个定义规则”(ODR),导致链接期符号冲突或未定义行为。

ExcelFormulaBot
ExcelFormulaBot

在AI帮助下将文本指令转换为Excel函数公式

下载
  • 根本原因:typeid(T) 可能生成全局 type_info 对象,而多个 TU 中定义相同类型时,若编译器未合并这些对象,就出问题
  • 规避方式:把 typeid 调用封进 constexpr 函数(C++17 起支持),或改用 std::type_identity_t<t></t> + decltype 等编译期手段代替运行时识别
  • 更实际的做法:避免在模板中直接依赖 typeid(T).name() 做逻辑分支;需要类型名时,用宏或特化 static constexpr char name[] = "MyType"

RTTI 开关对 typeiddynamic_cast 的实际影响

关闭 RTTI(如 GCC/Clang 加 -fno-rtti,MSVC 加 /GR-)后,typeiddynamic_cast 不再可用——编译器会直接报错,不是运行时报错。

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

  • 常见误判:以为 “typeid 还能用,只是不准”,其实连编译都过不去
  • 如果项目禁用 RTTI,又需要类型识别,只能靠手工维护类型 ID(如枚举 + getTypeId() 虚函数)或使用 std::any/std::variant(它们内部不依赖 RTTI)
  • 性能上,开启 RTTI 本身开销极小,主要成本在 dynamic_cast 的虚表遍历;但嵌入式或游戏引擎等场景仍常禁用,为的是减少二进制体积和确定性
RTTI 不是“开关一开就能用”的透明机制,typeid 的结果是否可信、能否跨编译单元稳定、甚至能不能编译通过,全取决于你是否踩中了 ABI、ODR、多态前提这些隐性条件。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

27

2025.11.27

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

707

2024.01.03

python中class的含义
python中class的含义

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

22

2025.12.06

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

49

2025.09.03

batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

127

2026.02.25

Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法
Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法

本专题系统整理Steam官网最新可用入口,涵盖网页版登录地址、新用户注册流程、账号登录方法及官方游戏商店访问说明,帮助新手玩家快速进入Steam平台,完成注册登录并管理个人游戏库。

18

2026.02.25

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

15

2026.02.25

Python数据处理流水线与ETL工程实战
Python数据处理流水线与ETL工程实战

本专题聚焦 Python 在数据工程场景下的实际应用,系统讲解 ETL 流程设计、数据抽取与清洗、批处理与增量处理方案,以及数据质量校验与异常处理机制。通过构建完整的数据处理流水线案例,帮助开发者掌握数据工程中的性能优化思路与工程化规范,为后续数据分析与机器学习提供稳定可靠的数据基础。

1

2026.02.25

Java领域驱动设计(DDD)与复杂业务建模实战
Java领域驱动设计(DDD)与复杂业务建模实战

本专题围绕 Java 在复杂业务系统中的建模与架构设计展开,深入讲解领域驱动设计(DDD)的核心思想与落地实践。内容涵盖领域划分、聚合根设计、限界上下文、领域事件、贫血模型与充血模型对比,并结合实际业务案例,讲解如何在 Spring 体系中实现可演进的领域模型架构,帮助开发者应对复杂业务带来的系统演化挑战。

1

2026.02.25

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 10.2万人学习

C 教程
C 教程

共75课时 | 5万人学习

C++教程
C++教程

共115课时 | 19.4万人学习

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

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