理解C++强制类型转换

理解C++强制类型转换

文章目录

  • 理解C++强制类型转换
  • 理解C++强制转换运算符
  • 1 static_cast
    • 1.1. static_cast用于内置数据类型之间的转换
    • 1.2 用于指针之间的转换
  • 2. const_cast
    • 2.1示例1
    • 2.2 示例2————this指针
  • 3.reinterpret_cast
  • 4.dynamic_cast

  1. C++认为C风格的类型转换过于松散,可能会带来隐患,不够安全。
  2. C++推出了新的类型转换来替代C风格的类型转换,采用更严格的语法检查,降低使用风险。
  3. C++新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast,用于支持C++风格的类型转换。
  4. C++的类型转换只是语法上的解释,本质上与C风格的类型转换没什么不同,C语言做不到事情的C++也做不到。

强制类型转换是有一定风险的,有的转换并不一定安全,如

  1. 1.把整型数值转换成指针
  2. 基类指针转换成派生类指针
  3. 一种函数指针转换成另一种函数指针
  4. 常量指针转换成非常量指针等。

总结:C语言强制类型转换缺点;主要是为了克服C语言强制类型转换的以下三个缺点。

  • 没有从形式上体现转换功能和风险的不同。
  • 将多态基类指针转换成派生类指针时不检查安全性,即无法判断转换后的指针是否确实指向一个派生类对象。
  • 难以在程序中寻找到底什么地方进行了强制类型转换强制类型转换是引发程序运行时错误的一个原因,因此在程序出错时,可能就会想到是不是有哪些强制类型转换出了问题。

例如,将int 强制转换成 double是没有风险的,而将常量指针转换成非常量指针,将基类指针转换成派生类指针都是高风险的,而且后两者带来的风险不同(即可能引发不同种类的错误),C语言的强制类型转换形式对这些不同并不加以区分

举例1. 把整型数值转换成指针,编译阶段不报错,运行阶段报错
在这里插入图片描述

理解C++强制转换运算符

C++ 引入了四种功能不同的强制类型转换运算符以进行强制类型转换

  • static cast
  • const cast
  • reinterpret_cast
  • dynamic_cast

语法:(目标类型)表达式或目标类型(表达式);

  1. static_cast<目标类型>(表达式);
  2. const_cast<目标类型>(表达式);
  3. reinterpret_cast<目标类型>(表达式);
  4. dynamic_cast<目标类型>(表达式);

1 static_cast

1.1. static_cast用于内置数据类型之间的转换

除了语法不同,C和C++没有区别。

#include <iostream>
using namespace std;int main(int argc, char* argv[])
{int ii = 3;long ll = ii;                     // 绝对安全,可以隐式转换,不会出现警告。double dd = 1.23;long ll1 = dd;                  // 可以隐式转换,但是,会出现可能丢失数据的警告。long ll2 = (long)dd;              // C风格:显式转换,不会出现警告。long ll3 = static_cast<long>(dd);    // C++风格:显式转换,不会出现警告。cout << "ll1=" << ll1 << ",ll2=" << ll2 << ",ll3=" << ll3 << endl;
}

1.2 用于指针之间的转换

C风格可以把不同类型的指针进行转换。
C++不可以,需要借助void *。

#include <iostream>
using namespace std;void func(void* ptr) {   // 其它类型指针 -> void *指针 -> 其它类型指针double* pp = static_cast<double*>(ptr);
}int main(int argc, char* argv[])
{int ii = 10;//double* pd1 = &ii;                      // 错误,不能隐式转换。double* pd2 = (double*) &ii;      // C风格,强制转换。//double* pd3 = static_cast<double*>(&ii);    // 错误,static_cast不支持不同类型指针的转换。void* pv = &ii;                               // 任何类型的指针都可以隐式转换成void*。double* pd4 = static_cast<double*>(pv);  // static_cast可以把void *转换成其它类型的指针。func(&ii);
}

2. const_cast

  1. static_cast不能丢掉指针(引用)的const和volitale属性,const_cast可以。
  2. 仅用于进行去除 const 属性的转换,它也是四个强制类型转换运算符中唯一能够去除 const 属性的运算符。
  3. const_cast 只针对指针,引用,this指针

2.1示例1

在这里插入图片描述
示例1改为

#include <iostream>
#include <string>
int main()
{const int n = 5;const std::string s = "Inception";//const_cast  只针对指针,引用,this指针int *k = const_cast<int*>(&n);//const_cast<int*>指针类型  &n取出变量地址*k = 123456;std::cout <<"改变后的值  "<< *k << std::endl;}

在这里插入图片描述

#include <iostream>
#include <string>
int main()
{const int n = 5;const std::string s = "Inception";//const_cast  只针对指针,引用,this指针int *k = const_cast<int*>(&n);//const_cast<int*>指针类型  &n取出变量地址int &k1 = const_cast<int&>(n);//const_cast<int&>引用类型 *k = 123456;k1 = 10000;std::cout <<"改变后的值  "<< *k << std::endl;std::cout << "改变后的值  " << k1 << std::endl;
}

在这里插入图片描述

2.2 示例2————this指针

常成员函数——不能修改成员变量的值


3.reinterpret_cast

static_cast不能用于转换不同类型的指针(引用)(不考虑有继承关系的情况),reinterpret_cast可以。
reinterpret_cast的意思是重新解释,能够将一种对象类型转换为另一种,不管它们是否有关系。
语法:reinterpret_cast<目标类型>(表达式);
<目标类型>和(表达式)中必须有一个是指针(引用)类型。
reinterpret_cast不能丢掉(表达式)的const或volitale属性。
应用场景:
1)reinterpret_cast的第一种用途是改变指针(引用)的类型。
2)reinterpret_cast的第二种用途是将指针(引用)转换成整型变量。整型与指针占用的字节数必须一致,否则会出现警告,转换可能损失精度。
3)reinterpret_cast的第三种用途是将一个整型变量转换成指针(引用)。
示例:

#include <iostream>
using namespace std;void func(void* ptr) {  long long ii = reinterpret_cast<long long>(ptr);cout << "ii=" << ii << endl;
}int main(int argc, char* argv[])
{long long ii = 10;func(reinterpret_cast<void *>(ii));
}

4.dynamic_cast

动态转换(dynamic_cast)用于基类和派生类之间的转换,但只能在运行时确定类型信息,因此只能用于多态类型。如果转换失败,将返回一个null指针。其语法如下:

dynamic_cast<目标类型> (原始类型)
以下是几个具体例子:

1、将一个基类指针强制转换为一个派生类指针:

class Base { virtual void f(){} };
class Derived : public Base { void f(){} };
Base *b = new Derived(); // 基类指针指向派生类对象
Derived *p = dynamic_cast<Derived *>(b); // 将基类指针转换为派生类指针

2、使用 dynamic_cast 对指针进行类型判断:

class Base {};
class Derived : public Base {};Base* b1 = new Derived();
Derived* d1 = dynamic_cast<Derived*>(b1);
if (d1 != nullptr) {// b1 是 Derived 类型的。
}

需要注意的是,如果指向的基类指针并不真正指向派生类,或者目标类型与原始类型之间的类型转换无法完成,dynamic_cast会返回null指针或抛出std::bad_cast异常。因此,在使用dynamic_cast时需要非常小心,确保程序的健壮性和安全性。

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

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

相关文章

【RabbitMQ 实战】08 集群原理剖析

上一节&#xff0c;我们用docker-compose搭建了一个RabbitMQ集群&#xff0c;这一节我们来分析一下集群的原理 一、基础概念 1.1 元数据 前面我们有介绍到 RabbitMQ 内部有各种基础构件&#xff0c;包括队列、交换器、绑定、虚拟主机等&#xff0c;他们组成了 AMQP 协议消息…

【GSEP202303 C++]】1级 每月天数

[GSEP202303 一级] 每月天数 题目描述 小明刚刚学习了每月有多少天&#xff0c;以及如何判断平年和闰年&#xff0c;想到可以使用编程方法求出给定的月份有多少天。你能做到吗&#xff1f; 输入格式 输入一行&#xff0c;包含两个整数&#xff0c;分别表示一个日期的年、月…

检测文件目录及其子文件到底的代码-实现可展开的目录列表和文件浏览功能的HTML代码

此实现了一个可展开的目录列表和文件浏览功能 该代码通过PHP实现了扫描指定目录下的文件和目录,并按照一定的排序规则进行展示。 用户可以点击目录名称,展开或折叠该目录下的子目录和文件列表。 对于文件,显示了文件名、修改时间和文件大小,并提供了文件链接以在新标签页…

uni-app 经验分享,从入门到离职(实战篇)——模拟从后台获取图片路径数据后授权相册以及保存图片

文章目录 &#x1f4cb;前言⏬关于专栏 &#x1f3af;需求描述&#x1f3af;前置知识点&#x1f9e9;uni.showLoading()&#x1f9e9;uni.authorize()&#x1f9e9;uni.downloadFile()&#x1f9e9;uni.saveImageToPhotosAlbum() &#x1f3af;演示代码&#x1f9e9;关于图片接…

一文了解硬盘AFR年化故障率评估方式和预测方案

目前常用评价硬盘&#xff08;或者其他硬件产品&#xff09;有一个关键的指标就是年化故障率&#xff08;AFR&#xff09;。年化故障率&#xff08;AFR&#xff09;是一种衡量产品可靠性的指标&#xff0c;表示在一年内产品发生故障的概率。 除了年化故障率&#xff08;AFR&…

Go Gin Gorm Casbin权限管理实现 - 2. 使用Gorm存储Casbin权限配置以及`增删改查`

文章目录 0. 背景1. 准备工作2. 权限配置以及增删改查2.1 策略和组使用规范2.2 用户以及组关系的增删改查2.2.1 获取所有用户以及关联的角色2.2.2 角色组中添加用户2.2.3 角色组中删除用户 2.3 角色组权限的增删改查2.3.1 获取所有角色组权限2.3.2 创建角色组权限2.3.3 修改角色…

API基础————包

什么是包&#xff0c;package实际上就是一个文件夹&#xff0c;便于程序员更好的管理维护自己的代码。它可以使得一个项目结构更加清晰明了。 Java也有20年历史了&#xff0c;这么多年有这么多程序员写了无数行代码&#xff0c;其中有大量重复的&#xff0c;为了更加便捷省时地…

【伪彩色图像处理】将灰度图像转换为彩色图像研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

选择适合户外篷房企业的企业云盘解决方案

“户外篷房企业用什么企业云盘好&#xff1f;Zoho WorkDrive企业网盘可以帮助户外篷房企业实现文档统一管理、提高工作效率、加强团队协作&#xff0c;并且支持各种文件类型的预览和编辑。” S公司是一家注重管理规范的大型户外篷房企业&#xff0c;已经有10余年的经验。作为设…

XSS CSRF

XSS & CSRF xss&#xff1a;跨站脚本攻击&#xff1a;注入一些非法的脚本 csrf&#xff1a;冒充身份 XSS 反射型 /welcome&#xff1a;res.send(req.query.type) 输入什么就输出什么&#xff08;httpOnly:false&#xff0c;但不是解决方案&#xff09; 比如&#xff1a;?&…

壁炉装饰:突破传统的创新趋势

壁炉&#xff0c;一直以来都是家庭温馨的象征&#xff0c;但它也是家居装饰中一个充满潜力的元素。如今&#xff0c;随着设计趋势的不断演变&#xff0c;壁炉装饰已经迈入了一个全新的时代&#xff0c;融合了美学、功能和可持续性&#xff0c;为家庭创造了更多可能性。 壁炉装饰…

openGauss学习笔记-91 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用MOT外部支持工具

文章目录 openGauss学习笔记-91 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用MOT外部支持工具91.1 gs_ctl&#xff08;全量和增量&#xff09;91.2 gs_basebackup91.3 gs_dump91.4 gs_restore openGauss学习笔记-91 openGauss 数据库管理-内存优化表MOT…

按键精灵调用大漠插件源码例子

源码名称&#xff1a;按键精灵调用大漠插件例子源码完整备注 源码名称&#xff1a;按键精灵调用大漠插件例子源码完整备注 蓝奏下载&#xff1a;https://wwi.lanzoup.com/iuffr0riiowf 飞书网盘&#xff1a;Docs

UG\NX二次开发 判断特征是否被抑制 UF_MODL_ask_suppress_feature

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 今日订阅 感谢 weixin_40668746 订阅本专栏,非常感谢。 简介 UG\NX二次开发 判断特征是否被抑制 UF_MODL_ask_suppress_feature. 函数说明 效果 可以…

VUE3照本宣科——package.json与vite.config.js

VUE3照本宣科——package.json与vite.config.js VUE3照本宣科系列导航 前言一、package.json1.name2.version3.private4.scripts5.dependencies6.devDependencies 二、vite.config.js1.plugins2.resolve.alias3.base4.mode 三、VUE3照本宣科系列总结 VUE3照本宣科系列导航 1.VU…

【LeetCode刷题笔记】双指针

剑指 Offer 21.调整数组顺序使奇数位于偶数前面 解题思路&#xff1a; 对撞指针 &#xff0c; 从左边不停的找第一个偶数&#xff0c;从右边不停的找第一个奇数 &#xff0c;找到后 交换 两者位置 本题与【905. 按奇偶排序数组】几乎雷同。 剑指 Offer 57.和为s的两个数字 本题…

Mac下docker安装MySQL8.0.34

学习并记录一下如何用docker部署MySQL 在Docker中搜索并下载MySQL8.0.x的最新版本 下载好后&#xff0c;在Images中就可以看到MySQL的镜像了 通过下面的命令也可以查看docker images启动镜像&#xff0c;使用下面的命令就可以启动镜像了docker run -itd --name mysql8.0.34 -…

Python爬虫——爬虫基础模块和类库(附实践项目)

一、简单介绍 Python爬虫是使用Python编程语言开发的一种自动化程序&#xff0c;用于从互联网上获取信息。通过模拟浏览器的行为&#xff0c;爬虫可以访问网页、解析网页内容&#xff0c;并提取所需的数据。 python的爬虫大致可以分为通用爬虫和专用爬虫&#xff1a; 通用爬虫…

【网络安全-信息收集】网络安全之信息收集和信息收集工具讲解

一&#xff0c;域名信息收集 1-1 域名信息查询 可以用一些在线网站进行收集&#xff0c;比如站长之家 域名Whois查询 - 站长之家站长之家-站长工具提供whois查询工具&#xff0c;汉化版的域名whois查询工具。https://whois.chinaz.com/ 可以查看一下有没有有用的信息&#xf…

攻防世界-T1 Training-WWW-Robots

文章目录 步骤1步骤二结束语 步骤1 看到文本——>提取有效信息——>利用有效信息 文本&#xff1a;In this little training challenge, you are going to learn about the Robots_exclusion_standard. The robots.txt file is used by web crawlers to check if they …