C++动态与静态转换区别详解
文章目录
- 前言
- 一、 类型检查的时机
- 二、安全性
- 三、适用场景
- 四、代码示例对比
- 总结
前言
在 C++ 中,dynamic_cast 和 static_cast 是两种不同的类型转换操作符,主要区别体现在类型检查的时机、安全性和适用场景上。以下是它们的核心区别:
一、 类型检查的时机
-
dynamic_cast:
运行时检查。它会验证转换的合法性(比如指针或引用是否指向目标类型的有效对象)。如果转换非法,对指针返回 nullptr,对引用抛出 std::bad_cast 异常。
要求类必须有虚函数(即多态类型),否则无法使用。 -
static_cast:
编译时检查。它信任开发者对类型安全的保证,不执行运行时检查。如果转换非法(比如无关类之间的转换),可能导致未定义行为(UB)。
适用于编译时已知类型关系的场景。
二、安全性
-
dynamic_cast:
更安全,但需要运行时开销(RTTI)。
主要用于多态类型的向下转型(downcast)或交叉转型(crosscast)。 -
static_cast:
不安全,但性能更高(无运行时开销)。
需要开发者自行确保类型兼容性,否则可能导致错误。
三、适用场景
dynamic_cast 的典型用途
- 多态类型(有虚函数的类)的向下转型:
class Base { virtual void foo() {} };
class Derived : public Base {};Base* ptr = new Derived;
Derived* derived_ptr = dynamic_cast<Derived*>(ptr); // 安全向下转型
- 处理继承层次中的交叉转换(如多重继承中的兄弟类转换)。
static_cast 的典型用途
- 基本类型的显式转换(如 double → int):
double d = 3.14;
int i = static_cast<int>(d);
- 非多态类型的指针/引用转换(需确保类型兼容):
Derived* d = new Derived;
Base* b = static_cast<Base*>(d); // 向上转型(安全,无需 dynamic_cast)
- 显式反向转换(如 void* → int*):
void* vptr = some_address;
int* iptr = static_cast<int*>(vptr);
四、代码示例对比
向下转型(多态类型)
class Base { virtual void foo() {} }; // 必须有多态性(虚函数)
class Derived : public Base {};Base* base_ptr = new Derived;// 使用 dynamic_cast(安全,但需要虚函数)
Derived* derived_ptr1 = dynamic_cast<Derived*>(base_ptr); // 成功// 使用 static_cast(不安全,但强制转换)
Derived* derived_ptr2 = static_cast<Derived*>(base_ptr); // 可能未定义行为(若实际类型不匹配)
class Base { virtual void foo() {} };
class Derived : public Base {};Base* ptr = new Derived;
Derived* derived_ptr = dynamic_cast<Derived*>(ptr); // 安全向下转型
非多态类型转换
class A {};
class B : public A {};A* a_ptr = new B;
B* b_ptr = static_cast<B*>(a_ptr); // 编译通过,但无运行时检查
// B* b_ptr = dynamic_cast<B*>(a_ptr); // 错误:A 不是多态类型(无虚函数)
总结
| 特性 | dynamic_cast | static_cast |
|---|---|---|
| 类型检查时机 | 运行时 | 编译时 |
| 安全性 | 高(失败返回 nullptr 或抛异常) | 低(依赖开发者保证) |
| 性能 | 有运行时开销(RTTI) | 无开销 |
| 适用类型 | 多态类型(需虚函数) | 任意类型(包括非多态) |
| 典型用途 | 向下转型、交叉转型 | 基本类型转换、显式向上/向下转型 |
优先选择 static_cast,除非需要处理多态类型的不确定转换(此时用 dynamic_cast)。
相关文章:
C++动态与静态转换区别详解
文章目录 前言一、 类型检查的时机二、安全性三、适用场景四、代码示例对比总结 前言 在 C 中,dynamic_cast 和 static_cast 是两种不同的类型转换操作符,主要区别体现在类型检查的时机、安全性和适用场景上。以下是它们的核心区别: 一、 类…...
Qt6.8编译项目找不到文件——6.8.2\msvc2022_64\include\QtWidgets\QMainWindow does not exist.
问题:Error: dependent ‘…\Qt6.8.2\6.8.2\msvc2022_64\include\QtWidgets\QMainWindow’ does not exist. jom: D:\Temp\untitled1\build\Makefile [release] Error 2 20:20:43: 进程"D:\ProgramFiles\Develop\Qt6.8.2\Tools\QtCreator\bin\jom\jom.exe"…...
AI工具导航平台功能模块之混合分类器功能说明文档
AI工具导航平台功能模块之混合分类器功能说明文档 这是我最近正在开发的AI工具信息平台的部门功能模块混合分类器的说明文档,我的AI工具信息平台基于streamlit架构,整理出来与大家分享。 该程序的混合分类器采用规则引擎与深度学习模型协同工作的架构&…...
【时序预测】在线学习:算法选择(从线性模型到深度学习解析)
——如何为动态时序预测匹配最佳增量学习策略? 引言:在线学习的核心价值与挑战 在动态时序预测场景中(如实时交通预测、能源消耗监控),数据以流式(Streaming)形式持续生成,且潜在的…...
某个设备的RJ45网口接头为何不可连接任何POE设备
某个设备的RJ45网口接头不可连接任何POE设备 1.POE设备是什么? POE设备是指支持通过以太网线传输电力和数据的设备,即“Power over Ethernet”(PoE)技术的设备。这种技术允许网络设备在传输数据的同时,通过标准的RJ4…...
发展中的脑机接口:SSVEP特征提取技术
一、简介 脑机接口(BCI)是先进的系统,能够通过分析大脑信号与外部设备之间建立通信,帮助有障碍的人与环境互动。BCI通过分析大脑信号,提供了一种非侵入式、高效的方式,让人们与外部设备进行交流。BCI技术越…...
绕过密码卸载360终端安全管理系统
一不小心在电脑上安装了360终端安全管理系统,就会发现没有密码,就无法退出无法卸载360,很容易成为一个心病,360终端安全管理系统,没有密码,进程无法退出,软件无法卸载,前不久听同事说…...
Java数据结构第十五期:走进二叉树的奇妙世界(四)
专栏:Java数据结构秘籍 个人主页:手握风云 目录 一、二叉树OJ练习题(续) 1.1. 二叉树的层序遍历 1.2. 二叉树的最近公共祖先 1.3. 从前序与中序遍历序列构造二叉树 1.4. 从中序与后序遍历序列构造二叉树 1.5. 根据二叉树创建…...
Transformer 代码剖析9 - 解码器模块Decoder (pytorch实现)
一、模块架构全景图 1.1 核心功能定位 Transformer解码器是序列生成任务的核心组件,负责根据编码器输出和已生成序列预测下一个目标符号。其独特的三级注意力机制架构使其在机器翻译、文本生成等任务中表现出色。下面是解码器在Transformer架构中的定位示意图&…...
JAVA八股—计算机网络(自用)
JAVA八股—计算机网络(自用) 2.7 1.介绍一下TCP/IP模型和OSI模型的区别 OSI模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,将计算机网络通信划分为七个不同的层级,每个层级都负责特定的功能。每个…...
unity和unity hub关系
unity和unity hub关系 Unity和Unity Hub是紧密相关但功能不同的两个软件,以下是它们的关系说明: Unity 定义:是一款专业的实时3D开发平台,广泛用于创建各种类型的3D和2D互动内容,如视频游戏、建筑可视化、汽车设计展示、虚拟现实(VR)和增强现实(AR)应用等。功能:提供…...
Linux的OOM机制
Linux 的 OOM(Out of Memory)机制是操作系统在内存耗尽时采取的一种保护措施。当系统内存不足,无法继续分配给进程时,Linux 内核会触发 OOM 杀手(OOM Killer),选择并终止某些进程,以…...
Typora的Github主题美化
[!note] Typora的Github主题进行一些自己喜欢的修改,主要包括:字体、代码块、表格样式 美化前: 美化后: 一、字体更换 之前便看上了「中文网字计划」的「朱雀仿宋」字体,于是一直想更换字体,奈何自己拖延症…...
Cursor配置MCP Server
一、什么是MCP MCP(Model Context Protocol)是由 Anthropic( Claude 的那个公司) 推出的开放标准协议,它为开发者提供了一个强大的工具,能够在数据源和 AI 驱动工具之间建立安全的双向连接。 举个好理解…...
定时器之输入捕获
输入捕获的作用 工作机制 输入捕获通过检测外部信号边沿(上升沿/下降沿)触发计数器(CNT)值锁存到捕获寄存器(CCRx),结合两次捕获值的差值计算信号时间参数。 脉冲宽度测量&#x…...
Uniapp开发微信小程序插件的一些心得
一、uniapp 开发微信小程序框架搭建 1. 通过 vue-cli 创建 uni-ap // nodejs使用18以上的版本 nvm use 18.14.1 // 安装vue-cli npm install -g vue/cli4 // 选择默认模版 vue create -p dcloudio/uni-preset-vue plugindemo // 运行 uniapp2wxpack-cli npx uniapp2wxpack --…...
0005__PyTorch 教程
PyTorch 教程 | 菜鸟教程 离线包:torch-1.13.1cpu-cp39-cp39-win_amd64.whl https://download.pytorch.org/whl/torch_stable.html...
Pikachu
一、网站搭建 同样的,先下载安装好phpstudy 然后启动Apache和Mysql 然后下载pikachu,解压到phpstudy文件夹下的www文件 然后用vscode打开pikachu中www文件夹下inc中的config.inc.php 将账户和密码改为和phpstudy中的一致(默认都是root&…...
CentOS7 使用 YUM 安装时报错:Cannot find a valid baseurl for repo: base/7/x86_64的解决方法
CentOS7 使用 YUM 安装时报错:Cannot find a valid baseurl for repo: base/7/x86_64的解决方法 报错代码解决方法 报错代码 输入命令yum update -y时报错Cannot find a valid baseurl for repo: base/7/x86_64 解决方法 有 wget 工具 更换YUM源 mv /etc/yum.…...
ChatGPT与DeepSeek:AI语言模型的巅峰对决
目录 引言 一、ChatGPT 与 DeepSeek 简介 (一)ChatGPT (二)DeepSeek 二、技术原理剖析 (一)ChatGPT 技术原理 (二)DeepSeek 技术原理 (三)技术原理对比…...
Linux----网络通信
一、IP地址详解 (一)核心概念 概念说明IP地址网络设备的唯一逻辑标识符,相当于网络世界的"门牌号"主机任何接入网络的终端设备(计算机/手机/服务器等)核心作用① 设备标识 ② 路由寻址 ③ 数据传输 &…...
Android逆向:一文掌握 Frida 详细使用
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. Frida 简介2. Frida 的工作原理3. 安装 Frida3.1 安装 Frida 工具3.2 安装 Frida Server4. Frida 的基本使用4.1 连接到目标设备4.2 附加到目标进程4.3 编写 Frida 脚本5. Frida 的高级用法5.1 Hook Java 方法5.2 修…...
AI军备竞赛2025:GPT-4.5的“情商革命”、文心4.5的开源突围与Trae的代码革命
AI军备竞赛2025:GPT-4.5的“情商革命”、文心4.5的开源突围与Trae的代码革命 ——一场重塑人类认知边界的技术战争 一、OpenAI的“感性觉醒”:GPT-4.5的颠覆与争议 1.1 从“冷面学霸”到“温柔导师”:AI的情商跃迁 当用户输入“朋友放鸽子&…...
5G网络切片辨析(eMBB,mMTC,uRLLC)
URLLC有三大应用场景,分别是eMBB(增强型移动宽带)、uRLLC(高可靠低延时通信)和mMTC(海量机器通信)。 增强型移动宽带(eMBB):需要关注峰值速率,容…...
【MySQL篇】数据类型
目录 前言: 1,数据类型的分类 编辑 2 ,数值类型 2.1 tinyint类型 2.2 bit类型 2.3 小数类型 2.3.1 float类型 2.3.2 decimal类型 3,字符串类型 3.1 char 3.2 varchar 3.3 char与varchar的比较 3.4日期和时间类型 3.5 …...
DockerでOracle Database 23ai FreeをセットアップしMAX_STRING_SIZEを拡張する手順
DockerでOracle Database 23c FreeをセットアップしMAX_STRING_SIZEを拡張する手順 はじめに環境準備ディレクトリ作成Dockerコンテナ起動 データベース設定変更コンテナ内でSQL*Plus起動PDB操作と文字列サイズ拡張設定検証 管理者ユーザー作成注意事項まとめ はじめに Oracle…...
Skynet入门(一)
概念 skynet 是一个为网络游戏服务器设计的轻量框架。但它本身并没有任何为网络游戏业务而特别设计的部分,所以尽可以把它用于其它领域。 设计初衷 如何充分利用它们并行运作数千个相互独立的业务。 模块设计建议 在 skynet 中,用服务 (service) 这…...
【音视频】图像基础概念
一、图像基础概念 1.1 像素 像素是一个图片的基本单位,pix使英语单词pixtureelement的结合“pixel”的简称,所以像素有图像元素之意。 例如2500*2000的照片就是指横向有2500个像素点,竖向有2000个像素点,总共500万个像素&#x…...
预训练(Pretraining)阶段为何被称为“自监督学习”(Self-Supervised Learning)?
预训练阶段为何被称为自监督学习? 在人工智能领域,尤其是自然语言处理(NLP)和深度学习的快速发展中,预训练(Pretraining)已经成为一种不可或缺的技术手段。而其中一个重要的概念是“自监督学习…...
【已解决】pyodbc 5.2 [ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序
问题 当升级 pyodbc 5.2 版本后,连接 sqlserver 数据库,报错如下: 连接失败: (IM002, [IM002] [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序 (0) (SQLDriverConnect); [IM002] [Microsoft][ODBC 驱动程序管理…...
