c++中static_cast和dynamic_cast区别_c++类型转换详解【进阶】
发布时间 - 2026-01-27 00:00:00 点击率:次static_cast适用于编译期安全的类型转换,如隐式允许的数值转换、有继承关系的指针/引用上下行转换(下行不安全)、const修饰增删;但不可用于无关类型指针转换。
static_cast 适合什么场景
static_cast 是编译期检查的显式类型转换,不涉及运行时开销。它能完成编译器隐式允许的转换(比如 int → double),也能在有明确继承关系的指针/引用间做上行或下行转换,但不做安全性验证。
- 上行转换(子类→父类)安全,和隐式转换等价,
static_cast只是显式写出意图 - 下行转换(父类→子类)危险:编译器信你,但若实际对象不是目标子类,运行时行为未定义
- 不能用于无关类型指针转换(比如
void→int需用reinterpret_cast) - 对于 const 修饰,可加/去 const,但去 const 后修改原 const 对象仍是未定义行为
class Base {};
class Derived : public Base {};
Base* b = new Base;
Derived* d = static_cast(b); // 编译通过,但运行时解引用会崩溃
dynamic_cast 为什么必须带 RTTI
dynamic_cast 专用于多态类型的指针/引用下行转换,依赖运行时类型信息(RTTI),因此要求基类至少有一个虚函数(通常是虚析构函数)。它会在运行时检查对象真实类型,安全失败而非崩溃。
- 指针转换失败返回
nullptr,引用转换失败抛出std::bad_cast异常 - 若基类无虚函数,编译直接报错:
error: cannot dynamic_cast ... because Base has no virtual functions - 转换成本高于
static_cast:每次调用都要查虚表、比对类型信息 - 不支持内置类型转换(如
int→float),那是static_cast
的事
class Base { virtual ~Base() = default; };
class Derived : public Base {};
Base* b = new Derived;
Derived* d = dynamic_cast(b); // 成功,d 指向有效对象
Base* b2 = new Base;
Derived* d2 = dynamic_cast(b2); // 失败,d2 == nullptr
什么时候该用 reinterpret_cast 或 const_cast
static_cast 和 dynamic_cast 都不覆盖所有转换需求,遇到以下情况得换别的 cast:
- 把任意指针转成
void*或反过来?用static_cast就够(前提是类型兼容) - 把
int强转成char做字节级操作?必须用reinterpret_cast,static_cast编译不过 - 想去掉
const修饰去写一个本就不该改的对象?const_cast是唯一合法方式,但后续写操作仍属未定义行为 -
dynamic_cast无法跨继承体系(比如从A转到完全无关的B),这种“暴力映射”只能靠reinterpret_cast,且极度危险
记住:能用 static_cast 的别用 reinterpret_cast;需要运行时校验的下行转换,别图省事用 static_cast 硬来。
常见误用和调试线索
很多 segfault 或逻辑错误,根源是 cast 用错。遇到这类问题先盯住三件事:
- 检查下行转换是否用了
static_cast而不是dynamic_cast,尤其在工厂函数或容器存基类指针后取用时 - 看基类有没有虚函数:没有就用不了
dynamic_cast,加个虚析构是最小代价修复 -
dynamic_cast返回nullptr却没检查?这是空指针解引用的高发原因 - 把
dynamic_cast用在非多态类型上,编译器会直接拒绝,别硬改语法绕过
RTTI 在某些嵌入式或性能敏感环境会被关闭(如 GCC 的 -fno-rtti),此时 dynamic_cast 不可用,只能靠设计规避下行转换,或者自己维护类型标识字段。
# 字节
# c++
# 区别
# 隐式转换
# 为什么
# Float
# 多态
# 父类
# 子类
# 析构函数
# Error
# const
# char
# int
# double
# void
# 指针
# 继承
# 虚函数
# 空指针
# 类型转换
# 对象
# 隐式
# 转成
# 只能靠
# 这是
# 都不
# 那是
# 都要
# 什么时候
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
php打包exe后无法访问网络共享_共享权限设置方法【教程】
焦点电影公司作品,电影焦点结局是什么?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
b2c电商网站制作流程,b2c水平综合的电商平台?
网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?
javascript基本数据类型及类型检测常用方法小结
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
如何用5美元大硬盘VPS安全高效搭建个人网站?
微信小程序 input输入框控件详解及实例(多种示例)
Laravel怎么自定义错误页面_Laravel修改404和500页面模板
消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工
Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境
再谈Python中的字符串与字符编码(推荐)
微信小程序 HTTPS报错整理常见问题及解决方案
Python面向对象测试方法_mock解析【教程】
如何在云主机快速搭建网站站点?
Linux系统命令中screen命令详解
详解Oracle修改字段类型方法总结
如何在VPS电脑上快速搭建网站?
jQuery中的100个技巧汇总
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
Python文件异常处理策略_健壮性说明【指导】
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
如何快速完成中国万网建站详细流程?
Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】
如何破解联通资金短缺导致的基站建设难题?
,交易猫的商品怎么发布到网站上去?
Laravel观察者模式如何使用_Laravel Model Observer配置
php增删改查怎么学_零基础入门php数据库操作必知基础【教程】
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
详解vue.js组件化开发实践
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
js实现点击每个li节点,都弹出其文本值及修改
Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
如何打造高效商业网站?建站目的决定转化率
详解Android——蓝牙技术 带你实现终端间数据传输
Laravel怎么调用外部API_Laravel Http Client客户端使用
如何在景安服务器上快速搭建个人网站?
Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
Python3.6正式版新特性预览
如何快速辨别茅台真假?关键步骤解析


