【c++11特性】——static_cast,dynamic_cast,const_cast,reinterpret_cast解析

目录

1.static_cast

2.dynamic_cast

dynamic_cast为什么只能用于具有虚函数的类?

3.const_cast

4.reinterpret_cast

reinterpret_cast 的作用

static_cast 和dynamic_cast的区别?


1.static_cast

概念

static_cast 是C++中的一种类型转换运算符,用于执行编译时的类型转换。它通常用于在编译时进行类型转换,而不进行运行时的检查。

static_cast 可以用于以下几种常见的类型转换:

1.基本数据类型的转换

static_cast 可以用于执行基本数据类型之间的转换,例如将整数转换为浮点数,反之亦然。

int integer = 42;
double floating = static_cast<double>(integer);

2.指针类型的转换

static_cast 可以用于执行指针类型之间的转换,但它通常不进行运行时检查。因此,你需要确保转换是安全的

Parent* parentPtr = new Child;
Child* childPtr = static_cast<Child*>(parentPtr);

如果你尝试将一个指向一个类的基类的指针转换为指向一个派生类的指针,但实际上该对象并不是派生类的实例,那么这个转换是不安全的。

class Base {};
class Derived {};Base* basePtr = new Base;
Derived* derivedPtr = static_cast<Derived*>(basePtr); // 不安全

在这种情况下,由于对象实际上不是 Derived 类的实例,这个转换会导致未定义的行为。

3.类层次结构中的向上转换

当你有一个指向派生类对象的指针,但需要将其转换为基类指针时,可以使用 static_cast 进行向上转换

Child* childPtr = new Child;
Parent* parentPtr = static_cast<Parent*>(childPtr);

2.dynamic_cast

dynamic_cast 是C++中的一种类型转换运算符,主要用于在类继承层次结构中执行安全的向上或向下类型转换,并进行运行时类型检查,dynamic_cast只能用于具有虚函数的类

作用:

安全的向下转换

  1. 当你有一个指向基类对象的指针或引用,但知道它实际上指向了某个派生类的对象时,可以使用 dynamic_cast 进行向下转换。它会在运行时进行类型检查,以确保转换是安全的。
  2. 如果基类指针或引用不指向派生类的对象,进行向下转换的时候,dynamic_cast 将返回 nullptr(对于指针),引发 std::bad_cast 异常(对于引用)
class Base {};
class Derived : public Base {};Base* basePtr = new Derived;
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr) {// 转换成功,可以安全地使用 derivedPtr
} else {// 转换失败
}

 

运行时类型检查

dynamic_cast 执行类型转换时会执行运行时类型检查确保对象的实际类型与所请求的类型匹配。如果类型不匹配,它会返回一个空指针(对于指针类型)或引发 std::bad_cast 异常(对于引用类型)。可以避免不正确的类型转换,提高了程序的健壮性。

以下是 dynamic_cast 的基本用法:

class Base {
public:virtual ~Base() {}
};class Derived : public Base {
public:void derivedFunction() {// 派生类特有的函数}
};int main() {Base* basePtr = new Derived;Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);if (derivedPtr) {// 转换成功,可以安全地访问派生类成员derivedPtr->derivedFunction();} else {// 转换失败}delete basePtr;return 0;
}

dynamic_cast为什么只能用于具有虚函数的类?

  • dynamic_cast 是一种在运行时执行类型检查的机制。它需要知道对象的实际类型,以便进行安全的类型转换
  • 每个具有虚函数的类都有一个虚函数表,其中存储了指向各种虚函数的指针,这个虚函数表允许在运行时查找对象的实际类型

总结:在运行的时候通过虚函数表指针去判断对象的实际类型

3.const_cast

const_cast 是C++中的一种类型转换运算符,它用于添加或删除对象的 const 限定符,以便在一定条件下进行类型转换。

作用:

1.去除 const 限定符

最常见的用途是用于const 类型的指针或引用转换为非 const 类型,这可以允许修改本来是 const 的对象,但需要小心使用,因为它可能会导致不一致的行为。

const int x = 42;
int* ptr = const_cast<int*>(&x);
*ptr = 55; // 可以修改 x,但是这是不推荐的

出现不一致的行为:

违反设计约定:在一些程序设计中,使用 const 是一种约定,用于表示某个对象应该被视为不可变。如果违反了这种约定,可能会导致程序中的错误。

2.添加 const 限定符

可以将非 const 类型的指针或引用转换为 const 类型,这通常用于传递对象的只读引用或指针,以防止在函数内部修改对象。

int y = 10;
const int* constPtr = const_cast<const int*>(&y);

4.reinterpret_cast

概念:

reinterpret_cast 是C++中的一种类型转换运算符,用于进行低级别的类型转换,通常用于不同类型之间的转换,或将整数值视为指针reinterpret_cast 非常强大,但也非常危险,因为它不进行类型检查。

reinterpret_cast 的作用

1.指针之间的转换

reinterpret_cast 可以用于将一个指针类型转换为另一个指针类型,即使它们之间没有继承关系。

int value = 42;
double* doublePtr = reinterpret_cast<double*>(&value);

这个转换不会执行任何类型检查,因此需要确保转换是安全的。 

2.整数和指针之间的转换

reinterpret_cast 还可以用于将整数值转换为指针,或将指针转换为整数值。这通常用于底层编程或处理硬件接口

int integer = 42;
void* voidPtr = reinterpret_cast<void*>(integer);

3.不同类型的指针之间的转换

有时需要将一个类型的指针转换为另一个类型的指针,但要注意这可能会导致未定义的行为,因为它假设了特定的内存布局。

struct A { int x; };
struct B { double y; };A* aPtr = new A;
B* bPtr = reinterpret_cast<B*>(aPtr); // 潜在的未定义行为

static_cast 和dynamic_cast的区别?

1.类型转换的时期

  • static_cast 是在编译时执行的类型转换
  • dynamic_cast 是在运行时执行的类型转换。它进行运行时类型检查,确保转换是安全的

2.安全性

  • static_cast 向下转换不安全:一个指向一个基类的指针转换为指向一个派生类的指针,但实际上该对象并不是派生类的实例,那么这个转换是不安全的
  • dynamic_cast 向下转换安全:运行的时候会检查如果基类指针或引用不指向派生类的对象,进行向下转换的时候,dynamic_cast 将返回 nullptr(对于指针),引发 std::bad_cast 异常(对于引用)

3.适用范围

  • static_cast适用非多态类型的转换,基本数据类型之间的转换,指针类型之间的转换
  • dynamic_cast 主要用于处理多态类型之间的转换,对象必须包含至少一个虚函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/94440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++设计模式之模板模式】分析及示例

C之模板模式 描述实现原理示例步骤1步骤1 分析步骤2步骤2 分析调用输出结果 结论 描述 模板模式&#xff08;Template Pattern&#xff09;是设计模式中的一种行为型模式。 该模式定义一个操作中的算法骨架&#xff0c;而将具体的算法实现延迟到子类中。 模板模式使得子类可以…

【10】c++设计模式——>依赖倒转原则

关于依赖倒转原则&#xff0c;对应的是两条非常抽象的描述&#xff1a; 1.高层模块不应该依赖低层模块&#xff0c;两个都应该依赖抽象。 2.抽象不应该依赖细节&#xff0c;细节应该依赖抽象。 先用人话解释一下这两句话中的一些抽象概念&#xff1a; 1.高层模块&#xff1a;可…

ROS(5)PX4仿真安装及运行

1、配置&#xff0c;提升下载速度 启动 $ cd clash-for-linux$ sudo bash start.sh$ source /etc/profile.d/clash.sh$ proxy_on 关闭 $ cd clash-for-linux$ sudo bash shutdown.sh$ proxy_off 2、安装PX4开源无人机 git clone https://github.com/PX4/PX4-Autopilot.git…

【软考】系统集成项目管理工程师(六)项目整体管理【6分】

一、 前言 1、项目管理三从四得 2、ITO共性总结 1、上一个过程的输出大部分是下-个过程的输入 2、计划和文件是不一样的 (每个输入都有计划和文件) 3、被批准的变更请求约等于计划 4、在执行和监控过程产生新的变更请求(变更请求包括变什么和怎么变&#xff0c;这是变更请求和…

Spring三大核心组件

Spring架构图 Spring三大核心组件分别为&#xff1a;Core、Beans和Context 1. Core&#xff08;核心&#xff09;&#xff1a; 思想&#xff1a;Core组件的核心思想是控制反转&#xff08;IoC&#xff09;和依赖注入&#xff08;DI&#xff09;。它将对象的创建、组装和管理的…

Junit的常用操作

注:本篇文章讲解的是junit5 目录 Juint是什么 Juint需要导入的依赖 Juint常用注解 Junit执行顺序 参数化 断言 测试套件 Juint是什么 Juint 是 Java 的一个单元测试框架. 也是回归测试框架. 使用 Junit 能让我们快速的完成单元测试。 注意&#xff1a;Junit 测试也是程序…

调用gethostbyname实现域名解析(附源码)

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

踩坑日记 《正确的使用Vuex》基于 uniapp Vue3 setup 语法糖 vuex4 项目 太多坑了要吐了

踩坑日记 《正确的使用Vuex》基于 uniapp Vue3 setup 语法糖 vuex4 项目 太多坑了要吐了 完美解决页面数据不刷新 或者数据慢一步刷新 页面使用html <template><view><template v-if"cartData.data.length>0"><!-- 自定义导航栏 --><…

计算机网络(文章链接汇总)

参考引用 计算机网络微课堂-湖科大教书匠计算机网络&#xff08;第7版&#xff09;-谢希仁 计算机网络&#xff08;一&#xff09;&#xff1a;概述计算机网络&#xff08;二&#xff09;&#xff1a;物理层计算机网络&#xff08;三&#xff09;&#xff1a;数据链路层计算机网…

SystemUI导航栏

SystemUI导航栏 1、系统中参数项1.1 相关开关属性2.2 属性设置代码 2、设置中设置“三按钮”导航更新流程2.1 属性资源覆盖叠加2.2 SystemUI导航栏接收改变广播2.3 SystemUI导航栏布局更新2.4 时序图 android13-release 1、系统中参数项 1.1 相关开关属性 设置->系统->…

测试用例的编写(面试常问)

作者&#xff1a;爱塔居 专栏&#xff1a;软件测试 作者简介&#xff1a;不断总结&#xff0c;才能变得更好~踩过的坑&#xff0c;不能再踩~ 文章简介&#xff1a;常见的几个测试用例。 一、淘宝购物车 二、登录页面 三、三角形测试用例 abc结果346普通三角形333等边三角形334…

【vue 首屏加载优化】

Vue 首屏加载优化指的是通过一系列的技术手段&#xff0c;尽可能地缩短首屏&#xff08;即页面中可见的部分&#xff09;的加载时间&#xff0c;提高用户体验。 以下是一些常见的 Vue 首屏加载优化技巧&#xff1a; 使用 Vue SSR&#xff08;服务端渲染&#xff09;&#xff1…

安装matplotlib_

安装pip 安装matplotlib 安装完毕 导入出现bug......

【LeetCode热题100】--35.搜索插入位置

35.搜索插入位置 使用二分查找&#xff1a; class Solution {public int searchInsert(int[] nums, int target) {int low 0,high nums.length -1;while(low < high){//注意每次循环完都要计算midint mid (low high)/2;if(nums[mid] target){return mid;}if(nums[mid]…

SpringCloudGateway网关中各个过滤器的作用与介绍

文章目录 RemoveCachedBodyFilterAdaptCachedBodyGlobalFilterNettyWriteResponseFilterForwardPathFilterRouteToRequestUrlFilterWebSocketRoutingFilterNettyRoutingFilterForwardRoutingFilterDispatcherHandler 是什么&#xff1f;⭐如何确定最后的路由路径&#xff1f;下…

聊天记录一句一句出现的视频制作,制作抖音聊天记录视频教程

聊天记录情感中视频制作工具是一款专注于将聊天记录转化为抖音视频的工具。它可以将平淡的聊天截图转化为生动有趣的视频&#xff0c;让你的回忆变得更加具有观赏性和情感共鸣。 首先&#xff0c;聊天记录一句一句出现的视频制作功能是该工具的一大特点。通过这个功能&#xf…

LLVM IR 文档 专门解释 LLVM IR

https://llvm.org/docs/LangRef.html#phi-instruction

[C++随想录] 优先级队列的模拟实现

优先级队列的模拟实现 底层结构初始化向下调整 && 向上调整push && poptop && empty && size源码 底层结构 namespace muyu {template <class T, class Continer std::vector<T>, class Compare less<T> >class priority_…

机器学习(监督学习)笔记

目录 总览笔记内容线性回归梯度下降特征缩放多输出线性回归 逻辑回归二分类与逻辑回归分类任务的性能指标&#xff08;召回率&#xff0c;精度&#xff0c;F1分数等&#xff09;支持向量机SVMK近邻朴素贝叶斯分类器朴素贝叶斯分类器进阶多分类逻辑回归二分类神经网络多分类神经…

代码随想录 Day10 栈与队列 LeetCode T239 滑动窗口的最大值 T347 前K个高频元素

简要介绍一下单调队列和优先级队列的不同 元素顺序的处理&#xff1a;单调队列中&#xff0c;元素的顺序是单调的&#xff0c;也就是说&#xff0c;队列中的元素按照特定的单调性&#xff08;递增或递减&#xff09;排列。这种特性使得单调队列在处理一些问题时非常高效&#…