0

0

C++中static_cast和dynamic_cast的区别?(静态转型与动态安全检查)

尼克

尼克

发布时间:2026-01-16 15:08:04

|

598人浏览过

|

来源于php中文网

原创

static_cast适用于编译期可确认的类型转换,如数值转换、向上转型或自定义转换函数;dynamic_cast依赖RTTI和虚函数表,仅用于多态类型的运行时安全向下转型,失败时指针返回nullptr、引用抛bad_cast。

c++中static_cast和dynamic_cast的区别?(静态转型与动态安全检查)

static_cast 适合什么场景

它做的是编译期能确认的类型转换,不涉及运行时类型检查。常见于数值类型转换、有明确继承关系的指针/引用向上转型(派生类 → 基类),或调用自定义的 operator T() 转换函数。

容易踩的坑:static_cast 允许向下转型(基类 → 派生类),但**不验证实际对象类型**,如果对象不是目标派生类实例,行为是未定义的。

  • int 转成 double:安全,编译器直接生成转换指令
  • Derived* 转成 Base*:安全,向上转型天然合法
  • Base* 转成 Derived*:危险,编译通过但可能崩溃

dynamic_cast 为什么需要虚函数表

dynamic_cast 依赖 RTTI(Run-Time Type Information),而 RTTI 只在至少有一个虚函数的类中才被编译器生成。它会在运行时检查对象的实际类型是否支持转换,只对多态类型(带虚函数的类)有效。

常见错误现象:dynamic_cast 对非多态类型(比如没有虚函数的 struct)编译失败,报错类似 cannot dynamic_cast ... (source type is not polymorphic)

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

Question AI
Question AI

一款基于大模型的免费的AI问答助手、总结器、AI搜索引擎

下载
  • 向下转型成功时返回目标类型的合法指针或引用
  • 向下转型失败时,对指针返回 nullptr,对引用抛出 std::bad_cast
  • 跨继承体系(如从一个基类转到另一个无关基类)也会失败

指针和引用的 behavior 差异

二者在失败处理上完全不同,这是最常被忽略的设计细节。

Base* b = new Base();
Derived* d1 = static_cast(b); // 编译通过,d1 指向非法内存
Derived* d2 = dynamic_cast(b); // 运行时检查,d2 == nullptr

Base& b_ref = *new Base(); try { Derived& d3 = dynamic_cast(b_ref); // 抛 std::bad_cast } catch (const std::bad_cast&) { // 必须捕获,否则程序终止 }

  • 用指针做 dynamic_cast:失败返回 nullptr,可安全判空
  • 用引用做 dynamic_cast:失败直接抛异常,不提供“检查失败”的机会
  • static_cast 对两者都不做运行时检查,失败后果由程序员承担

性能与设计意图的取舍

static_cast 零开销,dynamic_cast 有明显运行时成本:查虚函数表、遍历继承链、比较 type_info。它不是“更高级的 static_cast”,而是解决不同问题的工具

  • 已知对象确切类型?用 static_cast,比如工厂返回 Base* 但你 100% 知道它是 Derived
  • 不确定运行时类型,且必须安全向下转型?只能用 dynamic_cast
  • 想避免 dynamic_cast 的开销又需要类型分发?考虑 Visitor 模式或 std::variant + std::visit

真正容易被忽略的是:哪怕开了 RTTI,dynamic_cast 在多重继承或虚继承下仍可能因偏移计算变慢;而关闭 RTTI(如 GCC 的 -fno-rtti)会让所有 dynamic_cast 编译失败——这点在嵌入式或游戏引擎中常被遗忘。

相关专题

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

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

15

2025.11.27

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

538

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

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

197

2025.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

98

2025.10.23

C++类型转换方式
C++类型转换方式

本专题整合了C++类型转换相关内容,想了解更多相关内容,请阅读专题下面的文章。

295

2025.07.15

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

8

2026.01.16

热门下载

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

精品课程

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

共58课时 | 3.7万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.6万人学习

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

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