C++ dynamic_cast用法 C++ 运行时多态类型安全转换【RTTI】
发布时间 - 2026-01-28 00:00:00 点击率:次dynamic_cast只能用于多态类型,因为它依赖RTTI,而RTTI仅在含虚函数的类中生成;无虚函数则编译失败或抛std::bad_cast。
dynamic_cast 为什么只能用于多态类型
因为 dynamic_cast 依赖运行时类型信息(RTTI),而 RTTI 只在至少有一个虚函数的类中生成。没有虚函数的类,编译器不为其生成 vtable 和类型描述符,dynamic_cast 就会编译失败(指针转换)或抛出 std::bad_cast(引用转换)。
常见错误现象: er
- 确保源类和目标类都继承自有虚函数的基类(哪怕只有
virtual ~Base() = default;) - 不能对
void*、内置类型、普通结构体(无虚函数)做dynamic_cast - 向下转型(派生 → 基类)其实不需要
dynamic_cast,用隐式转换或static_cast更合适
指针转换失败时返回 nullptr,引用转换失败直接抛异常
这是最易踩的坑:用 dynamic_cast 转引用却没包 try/catch,程序崩溃;转指针却忘了判空,导致段错误。
示例:
Base* b = new Derived2(); Derived1* d1 = dynamic_cast(b); // 返回 nullptr if (d1) { /* 安全使用 */ } Derived1& r1 = dynamic_cast
(b); // 抛 std::bad_cast!
- 优先用指针形式,便于显式判空
- 非得用引用时,必须捕获
std::bad_cast - 别把
dynamic_cast当“万能安全转换”——它只解决“是不是这个确切类型”的问题,不是类型适配器
和 static_cast、reinterpret_cast 的关键区别在哪
dynamic_cast 唯一不可替代的场景是:在继承体系中,确认一个基类指针/引用**实际指向的是哪个具体派生类型**,且该判断必须发生在运行时。
-
static_cast:编译期检查,允许上行(派生→基类)、下行(基类→派生)甚至无关类型转换(如int→void*),但不验证实际对象类型,错用必 UB -
reinterpret_cast:完全绕过类型系统,仅重解释比特位,危险且与dynamic_cast零交集 -
dynamic_cast:仅限类层次间指针/引用转换,且只在 RTTI 启用、类型确实匹配时成功;其他情况明确失败(nullptr或异常)
性能影响:每次调用都有 vtable 查找 + 类型比较开销,高频循环里慎用。
RTTI 被禁用时 dynamic_cast 会怎样
某些嵌入式或性能敏感项目会通过编译选项(如 GCC/Clang 的 -fno-rtti)关闭 RTTI。此时 dynamic_cast 无法链接,报错类似:undefined reference to `typeinfo for ...'。
- 启用 RTTI 是使用
dynamic_cast的硬性前提,不是可选优化 - 关闭 RTTI 后,连
typeid也失效,所有依赖运行时类型识别的逻辑都要重构 - 若必须禁用 RTTI 又需类型判断,得手动实现(如加枚举字段 +
switch),但失去自动维护性和安全性
真正麻烦的不是语法怎么写,而是忘记 RTTI 是个开关——它关了,dynamic_cast 就彻底不存在,连编译都过不去。
# c++
# switch
# 区别
# 隐式转换
# 为什么
# for
# 多态
# try
# catch
# Error
# 派生类型
# 结构体
# int
# void
# 循环
# 指针
# 继承
# 虚函数
# 类型转换
# undefined
# 对象
# default
# 重构
# 只在
# 类中
# 的是
# 这是
# 就会
# 是个
# 都有
# 都要
# 不需要
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
北京企业网站设计制作公司,北京铁路集团官方网站?
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】
iOS UIView常见属性方法小结
Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环
利用JavaScript实现拖拽改变元素大小
Laravel Asset编译怎么配置_Laravel Vite前端构建工具使用
图册素材网站设计制作软件,图册的导出方式有几种?
Bootstrap整体框架之JavaScript插件架构
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
长沙企业网站制作哪家好,长沙水业集团官方网站?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
Linux系统命令中tree命令详解
Swift中循环语句中的转移语句 break 和 continue
如何在橙子建站中快速调整背景颜色?
如何安全更换建站之星模板并保留数据?
Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
php485函数参数是什么意思_php485各参数详细说明【介绍】
如何快速搭建高效WAP手机网站吸引移动用户?
JS中对数组元素进行增删改移的方法总结
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
javascript事件捕获机制【深入分析IE和DOM中的事件模型】
今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】
文字头像制作网站推荐软件,醒图能自动配文字吗?
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
使用spring连接及操作mongodb3.0实例
如何选择可靠的免备案建站服务器?
HTML 中如何正确使用模板变量为元素的 name 属性赋值
米侠浏览器网页背景异常怎么办 米侠显示修复
如何在 Pandas 中基于一列条件计算另一列的分组均值
如何有效防御Web建站篡改攻击?
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】
Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
java中使用zxing批量生成二维码立牌
如何登录建站主机?访问步骤全解析
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
网站建设整体流程解析,建站其实很容易!
创业网站制作流程,创业网站可靠吗?
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
如何用腾讯建站主机快速创建免费网站?
宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法
Firefox Developer Edition开发者版本入口
JS去除重复并统计数量的实现方法

