C++的类型转换之dynamic_cast

dynamic_cast介绍 首先说到c++常用的四中转换类型,我们都很清楚,分别是下面四中   1 const_cast  const_cast<目标类型>(标识符):目标类型只能是指针或者引用2 static_cast 类似C风格的强制转换,进行无条件转换,静态类型转换: 1)基类和子类之间的转换:其中子类指针转换为父类指针是安全的,但父类指针转换为子类指针是不安全的(基类和子类之间的动态类型转换建议用dynamic_cast)。 2)基本数据类型转换,enum,struct,int,cha... 阅读详情
AI摘要

本文介绍了C++中dynamic_cast用于多态类型指针或引用转换的情况。它可进行向上和向下转换,向上转换安全且隐式,向下转换需运行时检查。使用dynamic_cast能确保转换安全性,它依赖RTTI,相对更安全但有性能开销,适用于运行时确定对象类型的场景。

dynamic_cast 是 C++ 中用于安全地执行运行时类型转换的工具,主要用于多态类型(即继承结构)中的指针或引用转换。dynamic_cast 可以进行两种类型的转换:

  1. 向下转换 (Downcasting): 这是指从基类指针或引用转换为派生类指针或引用。向下转换需要确保基类指针或引用确实指向派生类的实例。dynamic_cast 会在运行时检查这种转换是否合法,如果转换不合法,dynamic_cast<指针类型> 将返回 nullptr,而 dynamic_cast<引用类型> 会抛出 std::bad_cast 异常。

  2. 向上转换 (Upcasting): 这是指从派生类指针或引用转换为基类指针或引用。向上转换是安全的,因为派生类对象总是包含基类对象的部分,所以这种转换总是可以安全地进行,dynamic_cast 在这种情况下不会进行任何运行时检查,也不会有错误发生。

向上转换(Upcasting)

向上转换是指将一个派生类的指针或引用转换为基类的指针或引用。在 C++ 中,向上转换是隐式且安全的,不需要使用 dynamic_cast,直接使用 static_cast 或直接赋值即可。这是因为派生类对象包含了基类的所有成员,所以可以安全地将其视为基类对象。

示例:

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void derivedFunction() {
        std::cout << "Derived function called" << std::endl;
    }
};

int main() {
    Derived* d = new Derived();
    Base* b = d; // 向上转换,隐式且安全

    // 使用基类指针访问基类成员
    delete b;
    return 0;
}

向下转换(Downcasting)

向下转换是指将一个基类的指针或引用转换为派生类的指针或引用。由于基类指针可能指向基类对象,也可能指向派生类对象,因此直接进行向下转换是不安全的,可能会导致未定义行为。dynamic_cast 可以用于这种转换,它会在运行时检查转换是否合法,如果转换不合法,返回 nullptr(对于指针)或抛出 std::bad_cast 异常(对于引用)。

示例:

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void derivedFunction() {
        std::cout << "Derived function called" << std::endl;
    }
};

int main() {
    Base* b = new Derived();
    Derived* d = dynamic_cast<Derived*>(b); // 向下转换,安全

    if (d != nullptr) {
        d->derivedFunction();
    }

    delete b;
    return 0;
}

在这种情况下,dynamic_cast 确保 b 实际上指向的是 Derived 类型的对象,然后再进行转换。

下向转换是否总是不安全?

向下转换并不总是不安全的,关键在于基类指针或引用是否确实指向派生类对象。使用 dynamic_cast 可以确保这种转换的安全性,因为它会在运行时检查对象的实际类型。如果确定基类指针或引用指向的是派生类对象,也可以使用 static_cast 进行向下转换,但这种转换不进行类型检查,因此是不安全的。

总结来说,dynamic_cast 提供了一种在运行时检查类型安全性的机制,适用于需要在运行时确定对象具体类型的场景,尤其是在多态性的情况下。向下转换的安全性依赖于运行时检查,而向上转换则是安全且隐式的。

演示向下转换不安全的情况

下面是一个简化的例子来说明 dynamic_cast 的使用:

#include <iostream>
#include <cassert>
#include <typeinfo>

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {
public:
    int derivedValue = 100;
};

int main() {
    // 创建一个Derived对象,并将其基类指针赋值给基类指针变量
    Base* basePtr = new Derived();
    
    // 向上转换总是安全的
    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
    assert(derivedPtr != nullptr);
    assert(derivedPtr->derivedValue == 100); // 成功转换

    // 尝试从基类指针转换为另一个不相关的派生类指针
    class OtherDerived : public Base {};
    OtherDerived* otherDerivedPtr = dynamic_cast<OtherDerived*>(basePtr);
    assert(otherDerivedPtr == nullptr); // 失败转换,返回nullptr

    // 向上转换为基类引用
    Derived& derivedRef = dynamic_cast<Derived&>(*basePtr);
    assert(derivedRef.derivedValue == 100); // 成功转换

    // 尝试从基类引用转换为另一个不相关的派生类引用
    try {
        OtherDerived& otherDerivedRef = dynamic_cast<OtherDerived&>(*basePtr);
        // 这里不会执行,因为dynamic_cast会抛出std::bad_cast异常
    } catch (std::bad_cast& e) {
        std::cout << "Caught a bad_cast exception: " << e.what() << std::endl;
    }

    delete basePtr;
    return 0;
}

在这个例子中,dynamic_cast 被用来演示向上转换和向下转换。向上转换将 Base* 转换为 Derived*,这是安全的,因为 basePtr 实际上指向一个 Derived 类型的对象,所以转换成功了。而向下转换尝试将 Base* 转换为 OtherDerived*,这是不安全的,因为 basePtr 不指向 OtherDerived 类型的对象,所以转换失败了,dynamic_cast 返回 nullptr。同样,dynamic_cast 尝试将 Base& 转换为 OtherDerived& 会导致抛出异常,因为转换是不安全的。

需要注意的是,dynamic_cast 只能用于包含虚函数的类层次结构中,因为它依赖于运行时类型信息(RTTI)。这使得 dynamic_cast 相对 static_cast 更安全,但也带来了一些性能开销。

总结来说,dynamic_cast 主要用于多态对象之间的安全转换,尤其是向下转换时,它提供了运行时错误检测的能力。

C++(03):dynamic_cast dynamic_cast主要用于有继承关系的多态类(基类必须有虚函数)的指针或引用之间的转换。1.通过dynamic_cast,将派生类指针转换为基类指针(上行转换),这个操作与static_cast的效果是一样的。2.通过dynamic_cast,将基类指针转换为派生类指针(下行转换),dynamic_cast具有类型检查的功能,比static_cast更安全(如果转换的是指针,失败时会返回空指针;如果转换的是引用,会抛出std::bad_cast异常)... 阅读详情

相关推荐

C++ 中dynamic_cast使用详解和实战示例

当不确定指针实际指向哪个派生类时,用 dynamic_cast。当能确定类型时,用 static_cast。基类必须有虚函数。失败返回 nullptr。

qq_36812406的博客 1020

C++基础#20:C++中的动态强制dynamic_cast

C++中提供了动态强制(dynamic_cast),是一种运行时类型识别机制,可以从一个虚的基类强制到一个派生类。我们常常需要知道,在运行过程中,我们真正在使用的是哪个类的对象,这时,可以明确地使用dynamic_cast来得到运行时类型的信息。

记录和分享程序人生的点点滴滴 1万+

当windows安装git时出现以下错误提示

Windows安装Git时出现多个系统配置设置失败错误(exit code 4294967295),提示包括无法设置textconv、LFS过滤器和SSL等配置项。关键问题在于scalar.exe版本不兼容,系统提示"该版本的scalar.exe与你运行的Windows版本不兼容"。解决方案是检查程序版本是否正确,下载与Windows系统兼容的正确版本重新安装即可。

沧澜的博客 1874

C++新特性08_强制转换dynamic_cast(具有虚函数基类的父转子的时候会存在越界问题,因此必须使用dynamic_cast在运行时检测转换是否安全、其本质是采用RTTI:运行时类型检测技术)

dynamic_cast用于具有虚函数的基类与派生类之间的指针或引用的转换。 使用的情况: (1)基类必须具备虚函数 原因:dynamic_cast是运行时类型检查,需要运行时类型信息(RTTI),而这个信息是存储与类的虚函数表关系紧密,只有一个类定义了虚函数,才会有虚函数表。 (2)运行时检查,转型不成功则返回一个空指针 (3)非必要不要使用DYNAMIC_CAST,有额外的函数开销 1.父类转子类情况下的越界问题: #include <iostream> #include <stri

分享学习成长历程,Winter is coming! 3398

Jenkins+docker 微服务实现自动化部署安装和部署过程

本文详细介绍了如何使用Docker部署Jenkins自动化服务器。主要内容包括:1)拉取Jenkins官方或BlueOcean镜像;2)创建容器并配置端口映射、数据卷挂载;3)设置防火墙规则;4)配置清华大学镜像加速;5)安装必要插件;6)SSH密钥配置;7)构建触发器设置;8)编写自动化构建脚本。通过Docker部署Jenkins可以简化安装流程,确保环境一致性,并利用容器特性实现快速启动和管理。文章提供了完整的配置步骤和注意事项,帮助用户快速搭建CI/CD环境。

qq_33665793的博客 1687

Altium Designer 18 将Gerber文件逆向转换成PCB(详细记录)

自己看了网上的教程,弄了很久,估计还有不足的地方,但是先把思路理一理(初学AD) 同时遇到了许多问题: 不是AD导出的Gerber估计不能自动识别层 要自己设置层顺序 要有钻孔文件数据制作NC工具(我也不懂是怎么说,就是size尺寸的) 这里记录一下,以防忘记。 正常顺序: 1.新建CAM 2.导入Gerber,选择CAM文件夹下的所有文件导入 3.设置层属性和物理顺序 4.设置NC工具 5.提取网络表 ...

lb_monkey的博客 1万+

【c++】c++的四种类型转换(static_cast,reinterpret_cast,const_cast,dynamic_cast)

前言 一、c语言中的类型转换 隐式类型转换 强制类型转换 const常变量的强制类型转换 总结 二、c++的四种类型转换 static_cast reinterpret_cast const_cast dynamic_cast 三、RTTI 总结

重铸自身根基的博客 1483

从噪声中提取真相:LabVIEW振动信号积分处理的降噪艺术

本文深入探讨了LabVIEW在振动信号积分处理中的降噪技术,揭示了如何通过选择性频率加权从噪声中提取关键故障特征。详细介绍了时域和频域积分方法的实现原理及优化策略,并结合工业案例展示了多轴信号联合降噪的实际应用效果,为设备状态监测提供了高效解决方案。

weixin_29164185的博客 300

C++ 强制类型转换:static_cast、dynamic_cast、const_cast 和 reinterpret_cast

C++ 强制类型转换:static_cast、dynamic_cast、const_cast 和 reinterpret_cast

Dong_HFUT的博客 9474

Python爬虫实战:利用Scrapy+Playwright高效爬取TED演讲数据

在当今信息爆炸的时代,TED演讲作为全球知名的思想传播平台,汇聚了各领域顶尖人才的精彩分享。对于数据分析师、研究人员或内容创作者来说,获取TED演讲的完整数据集具有重要价值。本文将详细介绍如何使用Python中最先进的爬虫技术组合——Scrapy框架配合Playwright浏览器自动化工具,高效爬取TED演讲的完整数据。传统爬虫技术在处理现代动态网页时面临诸多挑战,而本文将展示如何利用最新工具解决这些问题。

2201_76125261的博客 205

【数字IC刷题】华为海思数字IC笔试题(1)详细解析版

【数字IC刷题】华为海思数字IC笔试题(1)详细解析版

MoorePlus的博客 4214

C++ : 四种类型转换(static_cast,reinterpret_cast,const_cast,dynamic_cast)

综上,我们可以看到隐式类型转换的缺陷:转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换,c++提出了自己的四种转换,可以有效的处理这些问题。,它在静态区开空间进行存储数据,变量被const进行修饰具有常性,数据不可以被修改,但是我们可以通过类型转换,通过指针去修改它存储的数据的值,但是这种修改数据的值的方式是存在安全隐患的,因为我们使用const进行修饰变量,就是不希望数据被修改。关键字进行修饰变量,被volatile修饰的变量,编译器在取它的值的时候,每次都会去内存中去取。

2402_87310323的博客 1149

Authentication Assertion Tickets,SAP 系统到系统单点登录里的短命凭证

SAP 系统间的身份传递机制存在 Authentication Assertion Ticket 和 SAP Logon Ticket 两种易混淆的凭证。前者用于系统间短时身份委托(有效期2分钟,通过HTTP头传输),后者用于浏览器SSO(可配置有效期,通过Cookie传输)。Assertion Ticket依赖签发系统的数字签名和严格的时间同步,适用于ABAP/Java系统间的后台作业调用。现代SAP架构已转向OAuth 2.0等标准协议,但老系统中仍需注意两种票据的关键差异:传输方式、有效期、接收方限制

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 602

C++的四种强制类型转换详解,static_cast,reinterpret_cast,dynamic_cast,const_cast,C语言的隐式,显式类型转换详解

因为C++最重要的一个特性就是面向对象编程,对象就是由类构造而成的,C++有各种各样自定义的类,基类,派生类等等之间的转换强制使用以前的C风格转换不安全,简单点说,C++提供了四种更为安全规范的强制类型转换,分别为static_cast,reinterpret_cast,dynamic_cast,const_cast。说起C++的类型转换,必须首先的说C风格的类型转换,因为C++兼容C语言,C语言有两种类型转换,一种隐式的,一种显式的。重新解释类型(挂羊头,卖狗肉) 不同类型间的互转,数值与指针间的互转。

liu20000505的博客 2301

uniapp - 实现免费OCR文字识别方案,用户上传图片后进行扫描识别获取图片上的文字,uniApp纯前端做图片OCR识别——无需服务器进行OCR识别插件(不需要依赖任何SDK或第三方API服务)

uniapp实现orc识别免费的插件识别不花钱,无需第三方OCR文字识别API,uniApp拍照或者选择图片免费识别,纯前端不需要服务器,Uniapp提取图片上的文字,本地ocr识别技术,uni-app图片OCR识别文本,uniapp有没有免费的ocr识别组件,uniapp前端实现文字识别,身份证识别,营业执照识别 (兼容APP、H5、小程序 不需要任何SDK)跨端无SDK方案:Uniapp实现OCR文字,离线OCR识别,uniapp tesseract.js实现文字识别,uniapp文字识别无需依赖sdk

🏆 前端领域优质创作者 4244

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++:类型转换(static_cast、reinterpret_cast、const_cast、dynamic_cast)、RTTI

由于C语言两种类型转换方式都存在缺陷:隐式类型转换会导致诸如数据精度丢失等问题;而显示类型转化代码不清晰。所以C++在兼容C的基础之上,增加了4中强制类型转换:static_cast、reinterpret_cast、const_cast、dynamic_cast。 RTTI:Run-time Type identification的简称,即:运行时类型识别。typeid运算符dynamic_cast运算符decltype。

Zhenyu_Coder的博客 1454

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++ :C++ 的四种强制类型转换 static_cast、dynamic_cast、const_cast、reinterpret_cast

在上面所有形式中,e 的类型必须符合以下三个条件中的任何一个:e 的类型是是目标类型 type 的公有派生类、e 的类型是目标 type 的共有基类或者 e 的类型就是目标 type 的的类型。前两个的输出值是相同的,最后一个则会在原基础上偏移 4 个字节,这是因为 static_cast 计算了父子类指针转换的偏移量,并将之转换到正确的地址(c 里面有 m_a,m_b,转换为 B * 指针后指到 m_b 处),而 reinterpret_cast 却不会做这一层转换。这种转换的安全性也要开发人员来保证。

weiweiqiao的专栏 3607

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

[C++] 类型转换操作符(static_cast、dynamic_cast、const_cast、reinterpret_cast)

说明:本文主要解释static_cast、dynamic_cast、const_cast、reinterpret_cast这几种类型转换操作符。接下来我们对每一个类型转换操作符进行详细说明并给出一些基本的使用方式,重在深入理解。在解释类型转换操作符之前,我们先了解下,为什么要引入类型转换操作符?C语言本身就支持请值类型转换,那么C++为什么还要引入类型转换操作符呢,其实C++中引入类型转换操作符的设计目的是为了增强类型安全性和程序可靠性。

wangdsh的博客 1625

C++ 向上与向下类型转换(static_cast与dynamic_cast)

1、隐式转型(向上转型,即将派生类对象赋值给基类) C++允许向上转型,即将派生类的对象赋值给基类的对象是可以的,其只不过是将派生类中基类的部分直接赋给基类的对象,这称为向上转型(此处的“上”指的是基类),例如: class Base{ }; class Drived : public base{ }; Base* Bptr; Drive* Dptr; Bptr = Dptr; //编译正确,...

十一月zz的博客 1万+

C++四种类型转换 static_cast , reinterpret_cast ,const_cast ,dynamic_cast

介绍C++的四种类型转换,static_cast ,printerpret_cast,const_cast,dynamic_cast

2301_77509762的博客 1659

【C++类型转换】static_cast、dynamic_cast、const_cast、reinterpret_cast

中,并在后续标准(C++11/14/17/20)中保持稳定。这四大类型是 C++ 对 C 风格强制转换的现代化、安全化替代方案。在 C 语言中,类型转换通常使用。enum 与整型之间。

普罗米修斯的博客 693

掌握C++类型转换:static_cast、const_cast、dynamic_cast 和 reinterpret_cast

静态类型转换静态类型转换是最常用的类型转换方式,它可以将一种类型的数据强制转换为另一种类型,但需要注意的是,这种转换可能会损失一些信息,因此在进行此类转换时应当谨慎。int a = 10;动态类型转换动态类型转换主要用于多态类型之间的转换,它可以将基类指针或引用转换为派生类指针或引用。如果进行非法的类型转换,动态类型转换会返回一个空指针。重新解释类型转换。

Lion_Long的博客 6389

C++四种类型转换操作符 static_cast、dynamic_cast、reinterpret_cast、const_cast介绍

C风格的强制类型转换很简单,都可以使用Type b = (Type)a形式转换。但这种方式存在一些缺点,比如信息丢失或精度损失,代码可读性的下降等。因此C++提供了四种类型转换符来应对不同场合。分别是static_cast、dynamic_cast、reinterpret_cast、const_cast。

new9232的博客 1581

C++类型转换:static_cast、const_cast、reinterpret_cast、dynamic_cast

C++提供了四种类型转换操作符替代C风格强制转换:static_cast用于基础类型转换和继承体系向上转换,编译时检查;dynamic_cast用于多态类安全向下转型,运行时检查;const_cast用于修改const/volatile属性;reinterpret_cast用于底层位操作和指针转换,风险最高。这些转换操作符比C风格转换更安全明确,应优先使用。

qq_71320435的博客 1046

【C++】 四种强制类型转换(static_cast 与 dynamic_cast 的区别!)

强制类型转换1. static_cast2. const_cast3. reinterpret_cast4. dynamic_cast5. 为什么要需要四种类型转换? 1. static_cast 实现C++种内置基本数据类型之间的相互转换,不能用于两个不相关类型进行转换。 例如:将整形数据转换为浮点型 c语言方式 int a = 8; int b = 3; double result = (double)a / (double)b; C++方式 int a = 8; int b = 3; dou

lyly_h的博客 1万+

C++ 四种类型转换详解:static cast、dynamic cast、const cast、reinterpret cast 的使用场景

转换 | 编译期检查 | 运行期检查 | 类型安全性 | 主要限制 || 是 | 否 | 中 | 不能移除 const、不能转换无关类型 || 是(部分) | 是 | 高 | 必须有虚函数,有 RTTI 开销 |const_cast| 是 | 否 | 低 | 只能修改 const/volatile 属性 || 否 | 否 | 极低 | 几乎无约束,高度不可移植 |是日常使用最频繁的转换,处理编译期可验证的相关类型转换。记住它的“向下转型”是不安全的,除非你能确定实际类型。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 538
上一篇: C++预处理器中的#和##运算符
下一篇: Vmware16虚拟机下为Ubuntu22.04添加新的磁盘
吴_知遇
博客等级 码龄7年 100粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值