当前位置: 首页 > news >正文

为什么要使用dynamic_cast

博主介绍:程序喵大人

  • 35 - 资深C/C++/Rust/Android/iOS客户端开发
  • 10年大厂工作经验
  • 嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手
  • 《C++20高级编程》《C++23高级编程》等多本书籍著译者
  • 更多原创精品文章,首发gzh,见文末
  • 👇👇记得订阅专栏,以防走丢👇👇
    😉C++基础系列专栏
    😃C语言基础系列专栏
    🤣C++大佬养成攻略专栏
    🤓C++训练营
    👉🏻个人网站

开发了一个网站(希加加职业发展平台),可以对简历进行评估、并且能够根据你的简历内容进行面试押题预测,分享给大家。各位有需要的同学也可以去网站上实践体验一下,希望能帮助到你~

为什么需要dynamic_cast

dynamic_cast主要用于处理多态类型(即包含虚函数的类)的安全向下转型。与static_cast相比,它提供了运行时类型检查,确保转换的安全性。

static_cast的问题

static_cast在编译时执行类型转换,不进行运行时类型检查。当用于向下转型时(将基类指针转换为派生类指针),如果实际对象不是目标类型,会导致未定义行为(UB)。

关键区别

特性dynamic_caststatic_cast
检查时机运行时检查编译时检查
安全性安全,失败返回nullptr或抛出异常不安全,可能导致未定义行为
性能有运行时开销(RTTI)无运行时开销
适用场景多态类型间的转换非多态类型间的转换
失败处理返回nullptr(指针)或抛出异常(引用)无失败处理

直接看示例代码

#include <iostream>
using namespace std;class Base {
public:virtual ~Base() {} // 必须有虚函数才能使用dynamic_cast
};class Derived :public Base {
public:void derivedFunc() {cout << "Derived class function" << endl;}
};class OtherDerived :public Base {};int main() {// 情况1:正确的向下转型Base* b1 = new Derived();// 使用dynamic_cast - 安全Derived* d1 = dynamic_cast<Derived*>(b1);if (d1) {cout << "dynamic_cast to Derived successful" << endl;d1->derivedFunc();} else {cout << "dynamic_cast to Derived failed" << endl;}// 使用static_cast - 不安全但能编译Derived* d2 = static_cast<Derived*>(b1);cout << "static_cast to Derived (unsafe but works in this case)" << endl;d2->derivedFunc();// 情况2:错误的向下转型Base* b2 = new OtherDerived();// 使用dynamic_cast - 安全检测Derived* d3 = dynamic_cast<Derived*>(b2);if (d3) {cout << "dynamic_cast to Derived successful" << endl;} else {cout << "dynamic_cast to Derived failed (as expected)" << endl;}// 使用static_cast - 危险!未定义行为Derived* d4 = static_cast<Derived*>(b2);cout << "static_cast to Derived (unsafe and incorrect)" << endl;// 下面这行会导致未定义行为// d4->derivedFunc(); // 千万不要这样做!delete b1;delete b2;return 0;
}

如果上面的代码你没有触发未定义行为,可以看这个:

#include <iostream>
using namespace std;class Shape {
public:virtual ~Shape() {}virtual void draw() = 0;
};class Circle :public Shape {double radius;
public:Circle(double r) : radius(r) {}void draw() override {cout << "Drawing circle with radius: " << radius << endl;}double getArea() { return3.14159 * radius * radius; }
};class Square :public Shape {int side;
public:Square(int s) : side(s) {}void draw() override {cout << "Drawing square with side: " << side << endl;}int getPerimeter() { return4 * side; }
};int main() {// 创建一个Square对象,但用Shape指针指向它Shape* shape = new Square(10);// 危险:使用static_cast错误地转换为CircleCircle* circle = static_cast<Circle*>(shape);// 尝试访问Circle特有的成员函数和成员变量cout << "Circle area: " << circle->getArea() << endl;  // 这里的结果明显不会符合期望,甚至有可能崩溃// 实际对象是Square,但尝试当作Circle访问radius成员delete shape;return 0;
}

何时使用哪种转换

  1. 使用dynamic_cast:

    1. 当需要将基类指针/引用安全地转换为派生类指针/引用时
    2. 当不确定实际对象类型时
    3. 在多态类型层次结构中进行向下转型时
  2. 使用static_cast:

    1. 当进行基本类型之间的转换(如int到double)
    2. 当进行非多态类型之间的转换
    3. 当进行向上转型(派生类到基类)时(这是安全的)
    4. 当确定转换总是安全且需要避免dynamic_cast的性能开销时

性能考虑

dynamic_cast因为需要运行时类型检查(RTTI),所以比static_cast慢。在性能关键的代码中,如果能够保证转换的安全性,可以使用static_cast。但在大多数情况下,安全比微小的性能提升可能更重要。

码字不易,欢迎大家点赞,关注,评论,谢谢!

👉C++训练营

一个专为校招、社招3年工作经验的同学打造的 1v1 项目实战训练营,量身定制学习计划、每日代码review,简历优化,面试辅导,已帮助多名学员获得大厂offer!

http://www.dtcms.com/a/391696.html

相关文章:

  • 随机过程笔记
  • OpenHarmony:NDK开发
  • Dify 从入门到精通(第 87/100 篇):Dify 的多模态模型可观测性(高级篇)
  • 5种获取JavaScript时间戳函数的方法
  • Redis 三种集群模式
  • 初识kotlin协程
  • 多线程——内存可见性问题和指令重排序问题(volatile详解)
  • Linux第十八讲:应用层协议Http
  • 【C++】速识map与set
  • 多层感知机(MLP)
  • Linux系统诊断——拷贝日志系统
  • python中 ​实例方法​(普通方法)和 ​类方法​ 的核心差异
  • Sping AI接入deepseek-本地部署大模型-第二期
  • 数据分析-数据指标体系搭建及应用
  • 计算机专业课《大数据技术》课程导览:开启数据智能时代
  • dumpsys battery 简介
  • 从 CNN 基础到 AlexNet:计算机视觉的破局之路
  • 苏州自动化工厂1台服务器如何5人并发SolidWorks设计
  • 固态硬盘数据恢复一般多少钱?费用分析+恢复教程
  • WebRTC 探秘:构建你自己的实时视频应用
  • 在Ubuntu中离线安装miniconda3
  • Mem0 + 百度智能云向量数据库:为AI打造持久化记忆
  • MySQL 数据归档的技术困境与 Databend 解决之道
  • 2025icpc网络赛第一场The 2025 ICPC Asia East Continent Online Contest (I)
  • docker中ngnix的路径配置
  • 什么是黑板架构风格?
  • Redis 三大核心模式(主从复制 / 哨兵 / 集群):完整部署与问题解析
  • Docker生产环境容器OOM问题定位:镜像内存泄漏还是主机资源不足?
  • AcWing385. GF和猫咪的玩具——Floyd算法
  • 75、封装paddle ocr v5服务支持昇腾800 900 、800I A2、300I DUO卡推理识别