C++类型强转

C++(四)类型强转

新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强
制转换。C++提供了四种转化 static_cast,reinterpret_cast,dynamic_cast
和 const_cast 以满足不同需求,C++风格的强制转换好处是,它们能更清晰的表明
它们要干什么。

C 语言转换风格,在 C++中依然适用。

static_cast

语法格式static_cast(expression)
适用场景static_cast 是 C++ 中的一种类型转换操作符,用于在相关类型之间进行显式转换。它提供了比 C 风格的类型转换更严格的类型检查,并且在许多情况下比 reinterpret_cast 更安全。
1. 基本数据类型之间的转换
static_cast 可以用于基本数据类型之间的转换,例如将 int 转换为 float,或者将 double 转换为 int:int i = 42;float f = static_cast<float>(i); // 将 int 转换为 floatdouble d = 3.14;int j = static_cast<int>(d); // 将 double 转换为 intCopyInsert
2. 指针类型之间的转换
在指针类型之间进行转换时,static_cast 可以用于在相关类型之间进行转换,例如在基类指针和派生类指针之间进行转换:class Base {public:virtual void print() {std::cout << "Base" << std::endl;}};class Derived : public Base {public:void print() override {std::cout << "Derived" << std::endl;}};Base* basePtr = new Derived();Derived* derivedPtr = static_cast<Derived*>(basePtr); // 将基类指针转换为派生类指针derivedPtr->print(); // 输出 "Derived"CopyInsert
3. 枚举类型和整数类型之间的转换
static_cast 可以用于枚举类型和整数类型之间的转换:enum Color { RED, GREEN, BLUE };Color c = RED;int i = static_cast<int>(c); // 将枚举类型转换为整数类型int j = 1;Color c2 = static_cast<Color>(j); // 将整数类型转换为枚举类型CopyInsert
4. 空指针类型的转换
static_cast 可以用于将 void* 指针转换为具体类型的指针:void* voidPtr = malloc(sizeof(int));int* intPtr = static_cast<int*>(voidPtr); // 将 void* 指针转换为 int* 指针*intPtr = 42;CopyInsert
5. 移除 const 限定符
虽然 static_cast 不能直接移除 const 限定符,但可以通过 const_cast 移除 const 后,再使用 static_cast 进行转换:const int* constPtr = new int(42);int* nonConstPtr = const_cast<int*>(constPtr); // 移除 const 限定符int value = *nonConstPtr;

reinterpret_cast

语法格式reinterpret_cast(expression)
适用场景reinterpret_cast 是 C++ 中的一种类型转换操作符,用于将一种类型的指针转换为另一种类型的指针,即使这两种类型之间没有任何关系。reinterpret_cast 提供了最低级别的类型转换,通常用于需要直接操作内存布局的底层编程场景。
1. 指针类型之间的转换
在某些情况下,你可能需要将一个指针类型转换为另一个指针类型,而这些类型之间没有继承关系或其他明显的关联。例如:void* ptr = malloc(sizeof(int));int* intPtr = reinterpret_cast<int*>(ptr);*intPtr = 42;2. 函数指针的转换
在处理函数指针时,有时需要将一种类型的函数指针转换为另一种类型的函数指针。例如:typedef void (*FuncPtr)();void myFunction() {// 函数体}FuncPtr funcPtr = reinterpret_cast<FuncPtr>(&myFunction);funcPtr();3. 位模式的转换
有时需要将一个类型的位模式解释为另一个类型的位模式。例如,将一个整数转换为一个指针:int value = 42;void* ptr = reinterpret_cast<void*>(value);4. 处理底层硬件接口
在编写底层驱动程序或与硬件交互时,可能需要直接操作内存地址和寄存器。例如:volatile uint32_t* reg = reinterpret_cast<volatile uint32_t*>(0x12345678);*reg = 0xFFFFFFFF;5. 跨平台开发
在跨平台开发中,有时需要将数据结构从一个平台特定的表示转换为另一个平台特定的表示。例如:struct PlatformA {int value;};struct PlatformB {int value;};PlatformA a = {42};PlatformB* b = reinterpret_cast<PlatformB*>(&a);

const_cast

const_cast只有在将 const 添加到原始的非 const 时才是安全的
变量。尝试从原始 const 对象中删除 const 状态,以及
然后对其执行写入操作将导致未定义的行为。

总之,const_cast 是一种用于添加或移除指针或引用的 const 限定符的类型转换操作符。它主要用于在需要修改原本被声明为 const 的对象时,提供一种显式的方式来绕过 const 限制。然而,这种操作通常是不推荐的,应该谨慎使用。

语法格式const_cast(expression)
适用场景const_cast 是 C++ 中的一种类型转换操作符,用于移除 const 限定符。const_cast 用于将 const 指针转换为非 const 指针,或者将 const 引用转换为非 const 引用。const_cast 通常用于将 const 成员函数的 this 指针转换为非 const 指针,以便调用非 const 成员函数。它主要用于在需要修改原本被声明为 const 的对象时,提供一种显式的方式来绕过 const 限制。
1. 移除 const 限定符
在某些情况下,你可能需要修改一个原本被声明为 const 的对象。虽然这种操作通常是不推荐的,但在某些底层编程场景中可能是必要的。例如:const int a = 10;int* p = const_cast<int*>(&a); // 移除 const 限定符*p = 20; // 修改 const 对象的值2. 添加 const 限定符
虽然 const_cast 主要用于移除 const 限定符,但它也可以用于添加 const 限定符。例如:int b = 30;const int* cp = const_cast<const int*>(&b); // 添加 const 限定符3. 与非 const 成员函数一起使用
在某些情况下,你可能需要调用一个非 const 成员函数,但只有 const 对象的指针或引用。使用 const_cast 可以临时移除 const 限定符,调用非 const 成员函数,然后再恢复 const 限定符。例如:class MyClass {public:void nonConstFunction() {// 非 const 成员函数}};void foo(const MyClass* obj) {MyClass* nonConstObj = const_cast<MyClass*>(obj);nonConstObj->nonConstFunction();}4. 与 volatile 限定符一起使用const_cast 也可以用于添加或移除 volatile 限定符。例如:volatile int v = 42;int* vp = const_cast<int*>(&v); // 移除 volatile 限定符*vp = 50;

注意事项:

  1. 安全性:使用 const_cast 移除 const 限定符是非常危险的,因为它可能导致未定义行为。只有在确实需要修改原本被声明为 const 的对象时,才应该使用 const_cast。
  2. 可读性:使用 const_cast 会使代码的可读性降低,因为它明确地绕过了 const 限制。在可能的情况下,尽量使用其他更安全的方式来实现相同的功能。
  3. 替代方案:在可能的情况下,尽量使用 const 成员函数来处理 const 对象,避免使用 const_cast。

dynamic_cast

dynamic_cast 是 C++ 中的一种类型转换操作符,用于在运行时执行向下转型(downcasting)或向上转型(upcasting)。dynamic_cast 用于在运行时执行指针或引用的向上或向下转型,从而允许程序员在运行时判断指针或引用是否指向正确的类型。dynamic_cast 主要用于实现多态性(polymorphism),即不同类型的对象可以共享同一个基类。

dynamic_cast 与 static_cast 和 reinterpret_cast 不同,它不仅可以用于基本数据类型之间的转换,还可以用于指针、引用、成员指针、函数指针之间的转换。dynamic_cast 还可以用于类之间的转换,即使这两个类之间没有继承关系。

dynamic_cast 与 const_cast 类似,它也用于移除 const 限定符。但是,dynamic_cast 与 const_cast 不同,它可以用于执行向上或向下转型。

语法格式dynamic_cast(expression)
适用场景dynamic_cast 是 C++ 中的一种类型转换操作符,用于在运行时执行向下转型(downcasting)或向上转型(upcasting)。dynamic_cast 用于在运行时执行指针或引用的向上或向下转型,从而允许程序员在运行时判断指针或引用是否指向正确的类型。dynamic_cast 主要用于实现多态性(polymorphism),即不同类型的对象可以共享同一个基类。
1. 向下转型
dynamic_cast 可以用于执行向下转型(downcasting),即将指向派生类的指针或引用转换为指向基类的指针或引用。例如:class Base {public:virtual void print() {std::cout << "Base" << std::endl;}};class Derived : public Base {public:void print() override {std::cout << "Derived" << std::endl;}};Base* basePtr = new Derived();Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // 向下转型if (derivedPtr) {derivedPtr->print(); // 输出 "Derived"} else {std::cout << "Error: not a Derived object" << std::endl;}CopyInsert2. 向上转型
dynamic_cast 可以用于执行向上转型(upcasting),即将指向基类的指针或引用转换为指向派生类的指针或引用。例如:class Base {public:virtual void print() {std::cout << "Base" << std::endl;}};class Derived : public Base {public:void print() override {std::cout << "Derived" << std::endl;}};Base* basePtr = new Derived();Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // 向下转型if (derivedPtr) {derivedPtr->print(); // 输出 "Derived"} else {std::cout << "Error: not a Derived object" << std::endl;}CopyInsert3. 类之间的转换
dynamic_cast 可以用于类之间的转换,即使这两个类之间没有继承关系。例如:class Base {public:virtual void print() {std::cout << "Base" << std::endl;}};class Derived : public Base {public: void print() override {std::cout << "Derived" << std::endl;}};Base* basePtr = new Derived();Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // 向下转型if (derivedPtr) {derivedPtr->print(); // 输出 "Derived"} else {std::cout << "Error: not a Derived object" << std::endl;}CopyInsert4. 成员指针的转换
dynamic_cast 可以用于将成员指针转换为其他类型的成员指针。例如:class Base {public:virtual void print() {std::cout << "Base" << std::endl;}};class Derived : public Base {public:void print() override {std::cout << "Derived" << std::endl;}};Base* basePtr = new Derived();void (Base::*baseFunc)() = &Base::print;void (Derived::*derivedFunc)() = dynamic_cast<void (Derived::*)()>(baseFunc); // 成员指针转换(basePtr->*derivedFunc)(); // 输出 "Base"CopyInsert5. 函数指针的转换
dynamic_cast 可以用于将函数指针转换为其他类型的函数指针。例如:typedef void (*FuncPtr)();void myFunction() {// 函数体}FuncPtr funcPtr = &myFunction;void (*newFuncPtr)() = dynamic_cast<void(*)()>(funcPtr); // 函数指针转换newFuncPtr(); // 调用函数CopyInsert6. 空指针的转换
dynamic_cast 可以用于将空指针转换为其他类型的指针。例如:void* voidPtr = nullptr;int* intPtr = dynamic_cast<int*>(voidPtr); // 空指针转换if (intPtr) {std::cout << "Error: not a null pointer" << std::endl;} else {std::cout << "intPtr is a null pointer" << std::endl;}CopyInsert7. 转换失败时的行为
dynamic_cast 在转换失败时,会返回 nullptr。因此,在使用 dynamic_cast 时,需要先判断转换是否成功。例如:class Base {public:virtual void print() {std::cout << "Base" << std::endl;}};class Derived : public Base {public:void print() override {std::cout << "Derived" << std::endl;}};Base* basePtr = new Base();Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // 向下转型if (derivedPtr) {derivedPtr->print(); // 输出 "Base"} else {std::cout << "Error: not a Derived object" << std::endl;}CopyInsert8. 转换的安全性
dynamic_cast 转换的安全性与 static_cast 和 reinterpret_cast 类似。但是,dynamic_cast 转换的安全性比 static_cast 和 reinterpret_cast 更高,因为它可以执行多态性(polymorphism)转换。9. 转换的效率
dynamic_cast 转换的效率与 static_cast 和 reinterpret_cast 类似。但是,dynamic_cast 转换的效率比 static_cast 和 reinterpret_cast 更高,因为它可以在运行时执行转换。

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

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

相关文章

【深度学习】语音合成,TTS,PaddleSpeech

https://paperswithcode.com/task/text-to-speech-synthesis https://github.com/PaddlePaddle/PaddleSpeech https://github.com/coqui-ai/TTS https://github.com/keonlee9420/Expressive-FastSpeech2 https://github.com/TensorSpeech/TensorflowTTS docker镜像&#x…

【笔记】人工智能大模型在电力系统运行控制中的应用综述及展望

据统计,截至 2019 年底,我国风电和光伏的装机容量已经达到 415 GW,美国的可再生能源全年发电量已超过燃煤发电,同时欧洲计划在 2050 年完成 100% 可再生能源互联电网的建设。为了响应国家提出的“碳达峰”“碳中和”政策,国家电网公司提出在有效保障能源安全供应的前提下,…

嵌入式人工智能(31-基于树莓派4B的气压传感器-BMP280)

1、气压传感器 气压传感器&#xff08;Pressure Sensor&#xff09;是一种用于测量气体压力的装置。它可以将气体压力转换为电信号输出&#xff0c;进而实现对气体压力的监测和控制。气压传感器广泛应用于工业自动化、气象观测、建筑监测、航空航天等领域。 气压传感器的工作…

未来的智能农业:智能合约如何提升农业生产效率和可持续性

随着全球人口的增长和资源的有限性&#xff0c;农业生产面临着越来越大的挑战。如何在提高生产效率的同时保障可持续发展成为全球农业发展的关键问题。智能合约作为一种基于区块链技术的自动化执行合约&#xff0c;正在逐渐应用于农业领域&#xff0c;为农业生产带来了新的机遇…

Redis:RDB持久化

1. 简介 实现类似照片记录效果的方式&#xff0c;就是把某一时刻的数据和状态以文件的形式写到磁盘上&#xff0c;也就是 快照。这样一来即使故障宕机&#xff0c;快照文件也不会丢失&#xff0c;数据的可靠性也就得到了保证。 这个快照文件就称为RDB文件(dump.rdb)&#xff0c…

从代码层面熟悉UniAD,开始学习了解端到端整体架构

0. 简介 最近端到端已经是越来越火了&#xff0c;以UniAD为代表的很多工作不断地在不断刷新端到端的指标&#xff0c;比如最近SparseDrive又重新刷新了所有任务的指标。在端到端火热起来之前&#xff0c;成熟的模块化自动驾驶系统被分解为不同的独立任务&#xff0c;例如感知、…

数据倾斜优化思路实践

数据倾斜&#xff0c;顾名思义&#xff0c;就是在计算过程中数据分散度不够&#xff0c;导致某个节点数据过于集中&#xff0c;从而导致任务执行效率大大降低。参照对比下MR的整体流程和ODPS&#xff0c;整体结合理解数据倾斜发生的几个生命周期的节点&#xff0c;如下图&#…

WordPress设置固定连接后提示404

WordPress设置固定链接后出现404错误通常是因为服务器的伪静态规则没有正确设置。以下是几种常见的服务器环境下的解决方案&#xff1a; 宝塔面板&#xff1a;如果服务器安装了宝塔面板&#xff0c;可以在宝塔面板中选择对应的WordPress伪静态规则并保存设置 。 Apache服务器&a…

Linux——DNS服务搭建

&#xff08;一&#xff09;搭建nginx 1.首先布置基本环境 要求能够ping通外网&#xff0c;有yum源 2.安装nginx yum -y install nginx 然后查看验证 3.修改网页配置文件 修改文件&#xff0c;任意编写内容&#xff0c;然后去物理机测试 &#xff08;二&#xff09;创建一…

C++知识点总结:2.类和对象(自用)

类和对象 1. 类和对象的关系2. 对象指针3. 在堆上创建对象4. 成员访问限定符5. 名字编码&#xff08;Name Mangling&#xff09;6.构造函数7.构造函数的重载8.初始化列表8. 成员变量初始化的顺序&#xff08;通过初始化列表&#xff09;9. 初始化 const 成员变量10. 析构函数11…

【机器学习】pytorch 常用函数解析

目录 一、基本函数介绍 1.1 nn.Module 类 1.2 nn.Embedding 1.3 nn.LSTM 1.4 nn.Linear 1.5 nn.CrossEntropyLoss 1.6 torch.save 1.7 torch.load 1.8 nn.functional 1.9 nn.functional.softmax 本文主要对 pytorch 中用到的函数进行介绍&#xff0c;本文会不断更新~…

C语言内存函数精讲

目录 引言 1.内存分配函数malloc 2.内存释放函数free 3.内存拷贝函数memcpy 4.内存移动函数memmove 5.内存设置函数memset 6.内存比较函数memcmp 总结 引言 在C语言编程中&#xff0c;内存管理是核心技能之一。C语言提供了一系列内存操作函数&#xff0c;这些函数在动…

把Hexo博客迁移到新电脑

原文&#xff1a;https://blog.c12th.cn/archives/31.html 前言 把博客迁移到新电脑&#xff0c;以前推 Github 仓库不用配Key也能推&#xff0c;现在需要配Key了… 准备工作 确保在新电脑上配置好 Node.js 的环境 安装hexo npm install hexo-cli -g安装插件 npm install …

nmcli修改连接名 笔记240725

nmcli修改连接名 nmcli connection modify 原名 con-name 新名nmcli connection modify UUID con-name 新名通过网络名或uuid删除连接 nmcli connection delete 连接名或uuid通过设备名删除连接 nmcli device disconnect 设备连接用 nmcli device connect 设备名 创建的连接…

在android中怎么处理后端返回列表中包含图片id,如何将列表中的图片id转化成url

在 Android 中实现从包含图片 ID 的列表获取实际图片 URL 并显示图片,你可以使用以下步骤: 定义数据模型:创建一个 Java 或 Kotlin 类来表示列表中的对象。 网络请求:使用 Retrofit 或其他网络库来获取图片 URL。 异步处理:使用 AsyncTask、RxJava 或 Kotlin 协程来处理网…

算法训练 2024.7.27 17:25

目录 1. 两数之和2.反转链表3. 是否为有效的括号4.最长公共前缀5.合并两个有序数组6. 岛屿的个数7. 最小路径和8. 三数之和9. 计数质数10. 字符串转换整数 ( atoi) 1. 两数之和 题目&#xff1a; 给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为…

Python 在自动化中的实际应用:用 Python 简化繁琐任务

文章目录 1、概述2、自动化文件和目录管理3.数据处理与分析4.网页爬虫5. 系统管理6。定时任务7.结语 1、概述 这篇文章将深入探讨Python在自动化中的实际应用&#xff0c;帮助您用Python简化繁琐任务。 我们将从多个方面入手&#xff0c;展示如何利用Python进行文件管理、数据…

百度贴吧爬虫实战(BeautifulSoup+lxml)

文章目录 BeautifulSouplxml使用场景具体代码具体解析1. 导入模块2. 定义爬虫类3. 初始化方法4. 获取URL列表5. 获取页面内容6. 提取页面数据7. 保存数据8. 运行爬虫9. 主程序 总结 在实际爬虫之前还需要了解和下载两个模块&#xff1a;BeautifulSoup和lxml。 BeautifulSoup 和…

jmeter-beanshell学习-try处理异常

有时候代码执行过程中&#xff0c;出现一些不能处理的情况&#xff0c;就会报错&#xff0c;还影响之后的代码执行&#xff0c;就需要跳过异常。 上面这情况报错了&#xff0c;还影响了下面的打印。beanshell用try和catch处理异常&#xff0c;下面是try的用法&#xff0c;和if有…

PHP哈希签名方式sha1和sha256用于API对接签名验证

sha1 &#xff08;长度40字节&#xff09; -------------------------------------------------------------- $str 203fpid; $sha1 sha1($str); echo $sha1.<br>; php sha256加密 &#xff08;长度64&#xff09; --------------------------------…