static_cast,dynamic_cast,reinterpret_cast和c语言转换

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

大多程序员在学C++前都学过C,并且习惯于C风格(类型)转换。当写 C++(程序)时,有时候我们在使用static_cast<>和reinterpret_cast<>时可能会有点模糊。在本 文中,我将说明static_cast<>实际上做了什么,并且指出一些将会导致错误的情况。

泛型(Generic Types)

        float f = 12.3;
float* pf = &f;
  // static cast<>

        // 成功编译, n = 12
        int n = static_cast(f);

        // 错误,指向的类型是无关的(译注:即指针变量pf是float类型,现在要被转换为int类型)
        //int* pn = static_cast(pf);

        //成功编译
        void* pv = static_cast(pf);

        //成功编译, 但是 *pn2是无意义的内存(rubbish)
        int* pn2 = static_cast(pv);// reinterpret_cast<>

        //错误,编译器知道你应该调用static_cast<>
        //int i = reinterpret_cast(f);

        //成功编译, 但是 *pn 实际上是无意义的内存,和 *pn2一样
        int* pi = reinterpret_cast(pf);

简而言之,static_cast<> 将尝试转换,举例来说,如float-到-integer,而reinterpret_cast<>简单改变编译器的意图重新考虑那个对象作为另一类型。

指针类型(Pointer Types)

指针转换有点复杂,我们将在本文的剩余部分使用下面的类:

class CBaseX
      {
      public:

      int x;

      CBaseX() { x = 10; }

      void foo() { printf("CBaseX::foo() x=%d/n", x); }
      };

      class CBaseY
        {
        public:

        int y;

        int* py;

        CBaseY() { y = 20; py = &y; }

        void bar() { printf("CBaseY::bar() y

=%d, *py=%d/n", y, *py);

        }

        };

       class CDerived : public CBaseX, public CBaseY
       {
              public:
              int z;
        };
       情况1:两个无关的类之间的转换

      // CBaseX* 和 CBaseY*之间的转换

      CBaseX* pX = new CBaseX();

      // Error, types pointed to are unrelated

      // 错误, 类型指向是无关的
      // CBaseY* pY1 = static_cast(pX);
      // Compile OK, but pY2 is not CBaseX

      // 成功编译, 但是 pY2 不是CBaseX
      CBaseY* pY2 = reinterpret_cast(pX);

      // System crash!!
      // 系统崩溃!!
      // pY2->bar();

正如我们在泛型例子中所认识到的,如果你尝试转换一个对象到另一个无关的类static_cast<>将失败,而reinterpret_cast<>就总是成功“欺骗”编译器:那个对象就是那个无关类。

情况2:转换到相关的类

      1. CDerived* pD = new CDerived();
      2. printf("CDerived* pD = %x/n", (int)pD);
      3. 
      4. // static_cast<> CDerived* -> CBaseY* -> CDerived*
      //成功编译,隐式static_cast<>转换
      5. CBaseY* pY1 = pD;
      6. printf("CBaseY* pY1 = %x/n", (int)pY1);
      // 成功编译, 现在 pD1 = pD
      7. CDerived* pD1 = static_cast(pY1);
      8. printf("CDerived* pD1 = %x/n", (int)pD1);
      9. 
      10. // reinterpret_cast
      // 成功编译, 但是 pY2 不是 CBaseY*
      11. CBaseY* pY2 = reinterpret_cast(pD);
      12. printf("CBaseY* pY2 = %x/n", (int)pY2);
      13. 
      14. // 无关的 static_cast<>
      15. CBaseY* pY3 = new CBaseY();
      16. printf("CBaseY* pY3 = %x/n", (int)pY3);
      // 成功编译,尽管 pY3 只是一个 "新 CBaseY()"
      17. CDerived* pD3 = static_cast(pY3);
      18. printf("CDerived* pD3 = %x/n", (int)pD3);
      ---------------------- 输出 ---------------------------
      CDerived* pD = 392fb8
      CBaseY* pY1 = 392fbc
      CDerived* pD1 = 392fb8
      CBaseY* pY2 = 392fb8
      CBaseY* pY3 = 390ff0
      CDerived* pD3 = 390fec
注 意:在将CDerived*用隐式 static_cast<>转换到CBaseY*(第5行)时,结果是(指向)CDerived*(的指针向后) 偏移了4(个字节)(译注:4为int类型在内存中所占字节数)。为了知道static_cast<> 实际如何,我们不得不要来看一下CDerived的内存布局。

CDerived的内存布局(Memory Layout)

如 图所示,CDerived的内存布局包括两个对象,CBaseX 和 CBaseY,编译器也知道这一点。因此,当你将CDerived* 转换到 CBaseY*时,它给指针添加4个字节,同时当你将CBaseY*转换到CDerived*时,它给指针减去4。然而,甚至它即便不是一个 CDerived你也可以这样做。
当然,这个问题只在如果你做了多继承时发生。在你将CDerived转换 到 CBaseX时static_cast<> 和 reinterpret_cast<>是没有区别的。
情况3:void*之间的向前和向后转换
因为任何指针可以被转换到void*,而void*可以被向后转换到任何指针(对于static_cast<> 和 reinterpret_cast<>转换都可以这样做),如果没有小心处理的话错误可能发生。

        CDerived* pD = new CDerived();
        printf("CDerived* pD = %x/n", (int)pD);
        CBaseY* pY = pD; // 成功编译, pY = pD + 4
        printf("CBaseY* pY = %x/n", (int)pY);
        void* pV1 = pY; //成功编译, pV1 = pY
        printf("void* pV1 = %x/n", (int)pV1);
        // pD2 = pY, 但是我们预期 pD2 = pY - 4
        CDerived* pD2 = static_cast(pV1);
        printf("CDerived* pD2 = %x/n", (int)pD2);
        // 系统崩溃
        // pD2->bar();
        ---------------------- 输出 ---------------------------
        CDerived* pD = 392fb8
        CBaseY* pY = 392fbc
        void* pV1 = 392fbc
        CDerived* pD2 = 392fbc
一旦我们已经转换指针为void*,我们就不能轻易将其转换回原类。在上面的例子中,从一个void* 返回CDerived*的唯一方法是将其转换为CBaseY*然后再转换为CDerived*。
但是如果我们不能确定它是CBaseY* 还是 CDerived*,这时我们不得不用dynamic_cast<> 或typeid[2]。

注释:
1. dynamic_cast<>,从另一方面来说,可以防止一个泛型CBaseY* 被转换到CDerived*。
2. dynamic_cast<>需要类成为多态,即包括“虚”函数,并因此而不能成为void*。
参考:
1. [MSDN] C++ Language Reference -- Casting
2. Nishant Sivakumar, Casting Basics - Use C++ casts in your VC++.NET programs
3. Juan Soulie, C++ Language Tutorial: Type Casting

摘自:http://blog.youkuaiyun.com/jiangdf/archive/2009/05/21/4205481.aspx

dynamic_cast

      // Convert between CBaseX* and CBaseY*

作为四个内部类型转换操作符之一的dynamic_cast和传统的C风格的强制类型转换有着巨大的差别。除了 dynamic_cast以外的转换,其行为的都是在编译期就得以确定的,转换是否成功,并不依赖被转换的对象。而dynamic_cast则不然。在这 里,不再讨论其他三种转换和C风格的转换。
首先,dynamic_cast依赖于RTTI信息,其次,在转换时,dynamic_cast会检查转换的source对象是否真的可以转换成target类型,这种检查不是语法上的,而是真实情况的检查。
先 看RTTI相关部分,通常,许多编译器都是通过vtable找到对象的RTTI信息的,这也就意味着,如果基类没有虚方法,也就无法判断一个基类指针变量 所指对象的真实类型, 这时候,dynamic_cast只能用来做安全的转换,例如从派生类指针转换成基类指针.而这种转换其实并不需要dynamic_cast参与.
也就是说,dynamic_cast是根据RTTI记载的信息来判断类型转换是否合法的.
下面看一个例子:
struct B1{
    virtual ~B1(){}
};
struct B2{
    virtual ~B2(){}
};
struct D1 : B1, B2{};
int main()
{
    D1 d;
    B1* pb1 = &d;
    B2* pb2 = dynamic_cast(pb1);//L1
    B2* pb22 = static_cast(pb1);  //L2
    return 0;
}
上述定义中可以看到,B1和B2是不相关的类,从L1可以看到,dynamic_cast允许这种转换:只要B1存在多态方法.
L2将编译失败,static_cast并不允许两个完全不相干的类互相转换.
dynamic_cast的这种特性,在提取一个对象的某个接口的时候,非常有用,它很类似于实现了COM的QueryInterface的功能。
正好在网上看到一个讲解强制转型的文章:
http://www.xker.com/article/articleview/2005-8-23/article_view_2732.htm
文中这样描述:
--
dynamic_cast 主要用于执行“安全的向下转型(safe downcasting)”,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。
---这个描述是不完整的,dynamic_cast 固然可以实现完全的向下转型,也可以实现更为强大的QueryInterface的功能

从网格划分到结果解读:一次完整的子弹侵彻LS-DYNA仿真避坑指南 本文详细解析了子弹侵彻LS-DYNA仿真中的关键技术与避坑指南,涵盖网格优化、对称边界条件设置、沙漏控制参数调整及结果可信度验证。通过HyperMesh网格划分和LS-DYNA高级参数配置,帮助工程师提升仿真精度与效率,确保计算结果物理可信。 阅读详情

相关推荐

Java本地AI推理初体验:Jlama+LangChain4j构建离线问答系统

Jlama 是专为 Java 生态设计的现代化大型语言模型(LLM)推理引擎,旨在让开发者无需依赖外部服务即可直接在 Java 应用中运行本地化模型推理。本文将结合Jlama + langchain4j 实现一个本地可运行的简单问答Demo。

2501_92589102的博客 407

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

上述代码中,如果传入func函数的是子类对象的地址,那么在转换后pb1和pb2都会有对应的地址,但如果传入func函数的是父类对象的地址,那么转换后pb1会有对应的地址,而pb2则是一个空指针.const属性被去掉以后,会被修改!dynamic_cast只能用于含有虚函数的类,因为运行时类型检查需要运行时的类型信息,而这个信息是存储在虚函数表中的,只有定义了虚函数的类才有虚函数表.当然可以使用强制转换,这种转换时不安全的,会导致数据的丢失,原因是父类的指针或者引用的内存中可能不包含子类的成员的内存。

chuxinchangcun的博客 2208

react-window 大数据列表和表格数据渲染组件之虚拟滚动

ReactWindow是一个高性能的React虚拟滚动组件库,专门用于高效渲染大型列表和表格数据。它通过“窗口化”技术,仅渲染用户可见区域的内容,大幅提升性能并减少内存消耗。主要特点包括:支持固定/可变大小列表项、多种布局类型(垂直/水平/网格)、轻量级设计(不足5KB)以及平滑的滚动体验。相比传统渲染方式,它能轻松处理成千上万条数据,并提供自动滚动、自适应容器大小等高级功能。与同类库相比,ReactWindow具有更简洁的API和更优的性能表现,是处理大数据量渲染场景的理想选择。

前端开发-前端技术分享 1136

c语言cast的用法,reinterpret_cast 用法

reinterpret_cast 用法语法:reinterpret_cast(expression)如果 type-name 和 expression 的位数一样,那么就能进行这种转换。reinterpret_cast 的安全性完全由程序员控制。C语言的强制类型转换有时会忽略这一限制:转换源与转换目标的位数是否相同。例如,long 可以强制转换为 int,即“长数”强制转换为“短数”。char ...

weixin_33321522的博客 1531

遥感大模型的深度学习从CNN到Vision Transformer以及混合架构的演进之路

深度学习,特别是以卷积神经网络(CNN)和Transformer为代表的“大模型”技术,正以其强大的表征学习能力,深刻地重塑着遥感智能解译的整个技术栈与认知范式。本文将系统性地梳理遥感大模型从局部卷积的奠基,到全局注意力的革命,再到二者融合的混合架构演进这一波澜壮阔的历程。我们将深入剖析每个阶段的核心技术原理,结合遥感数据特性与实际应用案例,详细阐述其在分类、检测、分割等核心任务中的具体应用。

panshengwu的博客 1138

泛微Ecology9接口调用全流程:从配置到实战Java代码解析

本文详细解析了泛微Ecology9系统接口的完整调用流程,涵盖安全架构、服务端配置与客户端Java实战代码。重点阐述了基于RSA加密的认证机制、Token管理策略,并提供了企业级集成的核心代码示例与生产环境调优建议,帮助开发者安全、高效地实现系统对接。

m9n0o的博客 836

C/C++中的数据类型转换()/static_cast/dynamic_cast/const_cast/reinterpret_cast

C/C++属于静态语言,也就是在编译时变量的数据类型即可确定的强类型语言。当不同的数据类型在一起运算或者相互赋值的时候,就需要进行数据类型转换。不同数据类型占用的内存空间不同,而各种数据类型的转换时有规则的,一种通用的规则就是“小转大”自动进行,“大转小”需要强制执行。这里的“大”和“小”指的是数据范围...

AlbertS Home of Technology 1万+

组合导航、惯导、GNSS、INS、IMU的区别

‌:惯性导航系统(INS)是一种利用安装在运载体上的陀螺仪和加速度计来测定运载体位置的系统。它通过测量物体的加速度和角速度,结合算法计算出物体的位置、速度和姿态‌12。‌。

wynn1123的博客 8051

【C++】类型转换 ③ ( 重新解释类型转换 reinterpret_cast | 指针类型数据转换 )

一、重新解释类型转换 reinterpret_cast 1、指针数据类型转换 - C 语言隐式类型转换报错 ( 转换失败 ) 2、指针数据类型转换 - C 语言显示类型强制转换 ( 转换成功 ) 3、指针数据类型转换 - C++ 静态类型转换 static_cast ( 转换失败 ) 4、指针数据类型转换 - C++ 重新解释类型转换 reinterpret_cast ( 转换成功 )

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1361

YOLOv12模型详解及代码复现

YOLOV12算法详解及Python代码复现

hasakie的博客 6487

电磁兼容(EMC)整改案例(七):EFT测试失败都是IC悬空引脚惹的祸

无论任何时候,为了避免这些问题,通常建议对悬空的IO口进行适当的配置,比如设置为强推挽输出低电平、输入带上拉或下拉电阻等,以减少外部电路对IO管脚状态的影响,并提高系统的稳定性和可靠性.

linkking27的博客 1032

staticcast使用方法c语言,static_cast,dynamic_cast,reinterpret_cast和c语言转换

大多程序员在学C++前都学过C,并且习惯于C风格(类型)转换。当写 C++(程序)时,有时候我们在使用static_cast<>和reinterpret_cast<>时可能会有点模糊。在本 文中,我将说明static_cast<>实际上做了什么,并且指出一些将会导致错误的情况。泛型(Generic Types)float f = 12.3;float* pf =...

weixin_30140399的博客 897

C# 上位机之海康工业相机开发(SDK)实战教程

海康工业相机的C#开发核心是基于MVS SDK的“初始化→枚举→连接→采集→释放”流程,其中图像回调处理和格式转换是关键。严格按照SDK文档处理设备类型(网口/USB)和像素格式;及时释放图像资源,避免内存泄漏;错误码是排查问题的重要依据(可参考SDK中的“错误码说明”文档)。掌握这些基础后,可结合机器视觉算法(如OpenCV)实现缺陷检测、尺寸测量等高级功能,构建完整的工业视觉系统。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 3829

C++强制类型转换运算符(static_cast、reinterpret_cast、const_cast和dynamic_cast)克服C语言把常量指针转换成非常量指针等风险

将类型名作为强制类型转换运算符的做法是C语言的老式做法,C++为保持兼容而予以保留。 C++ 引入了四种功能不同的强制类型转换运算符以进行强制类型转换:static_cast、reinterpret_cast、const_cast 和 dynamic_cast。强制类型转换是有一定风险的,有的转换并不一定安全,如把整型数值转换成指针,把基类指针转换成派生类指针,把一种函数指针转换成另一种函数指针...

二进制模----细微行动改变影响世界 427

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

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

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

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

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

重铸自身根基的博客 1484

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C++强制类型转换运算符(static_cast、reinterpret_cast、const_cast和dynamic_cast)

将类型名作为强制类型转换运算符的做法是C语言的老式做法,C++为保持兼容而予以保留。 C++ 引入了四种功能不同的强制类型转换运算符以进行强制类型转换:static_cast(静态转换)、reinterpret_cast(重新解释(类型的比特位))、const_cast(常量转换) 和 dynamic_cast(动态转换)。 强制类型转换是有一定风险的,有的转换并不一定安全,如把整型数值转换成指针,把基类指针转换成派生类指针,把一种函数指针转换成另一种函数指针,把常量指针转换成非常量指针等。C++ 引入新.

顺其自然~专栏 1935

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

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

2402_87310323的博客 1149

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

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

2301_77509762的博客 1659

【C++入门到精通】C++类型的转换 | static_cast | reinterpret_cast | const_cast | dynamic_cast [ C++入门 ]

本文将继续讲解C++类型的转换,主要介绍static_cast、reinterpret_cast、const_cast和dynamic_cast这四种类型转换操作符的用法和特点。在C++中,类型转换是一种将一个数据类型转换为另一个数据类型的机制,用于在编程过程中灵活地处理不同数据类型之间的转换需求。本文将依次介绍这四种类型转换操作符的作用和适用场景,并给出相应的示例代码以说明其用法。同时,对于每种类型转换操作符,还会探讨其使用时需要注意的问题,以确保类型转换的安全性和正确性。

Yawesh的博客 1587

c++的类型转换static_cast、reinterpret_cast、const_cast、dynamic_cast

c++的类型转换static_cast、reinterpret_cast、const_cast、dynamic_cast

zgwnb666的博客 789

C++中的dynamic_cast和static_cast转化

一、先说C语言,C语言中有两种类型转化: (1)隐式转化 int i; float j = i; (2)显式转化 void *p; int *a = (int*)p 二、谈一谈C++中的两种标准类型转化:static_cast、dynamic_cast C++作为C语言的扩展仍然支持C语言中原有的类型转化方式,但是由于多加了“类“,所以C++对于类型转化需要更高的安全保

王迪 667

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

【本文转载自】【C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast - SpartacusIn21 - 博客园】侵权请告知删除,谢谢! 1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2 c++除了能使用c语言的强制类型转换外,还新增了四种强制类型转换:static_cast

SHK242673的专栏 569

C/C++类型转换(C++四大强制类型转换)

总是一个“与指针类型占用字节数相同,却是一个整型类型”的数据类型的重命名,也就是说,在32位系统下(指针大小是4字节),他两分别是usigned long和long;进行上行转换(把派生类的指针或引用转换成基类表示)是安全的,进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。在者,在某些位数的操作系统中,指针与小数类型数据的字节数可能不同(比如16位系统下),强行转换会有丢失数据的风险,这是兼容性的考虑。没问题吧,基础类型之间的转换,那我把。

2302_80221042的博客 1300

【C++】C++的类型转换 {C++的四种类型转换:static_cast,reinterpret_cast,const_cast,dynamic_cast;RTTI 运行时类型识别}

【C++】C++的类型转换 {C++的四种类型转换:static_cast,reinterpret_cast,const_cast,dynamic_cast;RTTI 运行时类型识别}

52Herzt的博客 1591

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

本文主要讲:隐式类型转换与C语言的显示类型转换,C++四种显示类型转换(重点),const_cast、static_cast、dynamic_cast、reinterpret_cast。

weixin_61360713的博客 498
上一篇: MFC,ATL,CLR简介
下一篇: abort、exit、atexit、strerror函数的使用方法
Hashmat
博客等级 码龄16年 14粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值