当前位置: 首页 > news >正文

C++中的类型转换操作符:static_cast reinterpret_cast const_cast dynamic_cast

目录​​​​​​​

C语言中的类型转换

C++中的类型转换

C++中的类型转换操作符

static_cast

reinterpret_cast

const_cast

volatile关键字

赋值兼容

dynamic_cast


C语言中的类型转换

基本概念:赋值运算符左右两侧类型不同,或形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,需要发生类项转换,C语言中有两种形式的类型转换,隐式类型转换和显示类型转换

注意事项:有关联的类型才可以相互转换,小类型会转换为大类型

  1. 整型之间的隐转(int、long、short)
  2. 整型和浮点数间的隐转
  3. 整型和字符型间的隐转
  4. bool和整型、指针间的隐转(整数0和空指针均表示假)
  5. 整型和指针间的强转(地址的本质是一个编号所以可以)
//整型转换为指针
//缺点:在绝大多数情况下是不安全的,除非你确切知道这个整数表示的内存地址是有效的
int number = 1234;
int *ptr = (int *)number;//指针转换为整型:通常用于获取指针的内存地址
//缺点:如果在64位系统上,将指针转换为32位整数(如 int),可能会导致数据丢失。因此,建议使用 intptr_t 或 uintptr_t 类型,它们在 <stdint.h> 头文件中定义,可以确保适当的大小来存储指针值
int *ptr = &number;
int address = (int)ptr;

关于intptr_t和uintptr_t可以查看:intptr_t、uintptr_t数据类型的解析

  1. 不同类型的指针间的强转
//不同类型的指针间的强制类型转换
char s = 'a';
char* ptr1 = &s;
int* ptr2 = (int*) ptr1;

显示类型转换的缺点:

  • 可能导致数据丢失当从一个较大的数据类型转换为一个较小的数据类型时,可能会丢失数据。例如,将 double 转换为 int 时,小数部分会被截断
double d = 3.14; int i = (int)d; // i = 3, 小数部分丢失
  • 降低代码可读性频繁使用显式类型转换会使代码变得难以阅读和理解,尤其是当类型转换逻辑复杂时
float f = (float)((int)doubleValue * 2.0);
  • 增加错误风险进行类型转换时,容易忽略一些潜在的错误,如溢出或数据精度问题,导致难以发现的bug
long longValue = 1234567890123456789LL; 
int intValue = (int)longValue; // 可能会溢出

隐式类型转换的缺点:

  • 隐蔽的数据丢失int 转换为 float 时,如果整数的值超过了浮点数的精度范围,可能会丢失精度

int i = 123456789; float f = i; // 可能会丢失精度
  • 难以调试和维护隐式类型转换发生在幕后,可能导致意外的结果和难以调试的问题。出错时需要仔细检查代码,以确保所有隐式转换都符合预期

//int被转换为size_t,当传入的pos = 0时,会陷入死循环 
void Insert(size_t pos)
{int end = 10;// 比较的时候end会隐式类型转换成size_t,再比较while (end >= pos){cout << end << "挪走" << endl;--end;}
}

C++中的类型转换

基本概念:C++中通过构造函数和重载可以实现内置类型与自定义类型间、自定义类型间的转换

  • 内置类型->自定义类型:借助构造函数,隐式类型转换
//单参数的构造函数,支持内置类型隐式转换成自定义类型
string s1 = "111111";
const string& s2 = "11111";
  • 自定义类型->内置类型:重载某个类型(operator +类型名)
class A
{
public:operator int(){return _a1 + _a2;}
private:int _a1 = 1;int _a2 = 2;
};int main()
{A aa;int a = aa;int b = (int)aa;cout << a << endl;cout << b << endl;return 0;
}

  • 自定义类型->自定义类型:借助构造函数进行隐式类型转换(initializer_list和容器间)

C++中的类型转换操作符

基本概念:C++依然兼容C语言的两种类型转换方式,但是为了加强类型转换时的可视性,C++引入了四种类型转换操作符,它们是一些进行类型转换时的命名建议,并不强制

static_cast

基本概念:进行有关联的类型间的隐式类型转换(编译时进行,也叫静态转换)

int main()
{//C++的隐式类型转换:明显double d = 12.34;int a1 = static_cast<int>(d);cout << a1 << endl;//12//C语言的隐式类型转换:不明显int a2 = d;cout << a2 << endl;//12return 0;
}

reinterpret_cast

音标:riːɪnˈtɜːrprət

基本概念:进行强制类型转换,不进行类型检查

int main()
{int a = 12;// int* p = static_cast<int*>(a); 报错,int和int*不是两个相关的类型int* p = reinterpret_cast<int*>(a);cout << p << endl;return 0;
}

const_cast

基本概念:删除对象的const属性

int main()
{const int a = 10;int* p = const_cast<int*>(&a); // 去除const属性*p = 20; // 尝试修改值cout << a << endl;//a == 10cout << *p << endl;//*p == 20return 0;
}

        对比监视列表和控制台,可以发现虽然在内存中a的值变为了20,但是打印时a仍为原来的10,这是因为编译器知道const修饰的变量不会被修改,那么编译器在编译阶段就会对其优化,即编译器会将常量的值直接内联到使用该常量的地方,而不是每次都访问内存中的存储位置,这一优化技术称为“常量折叠”或“常量传播

补充:const修饰的局部变量仍然存放在栈上,修饰的全局变量才放在常量区中

volatile关键字

基本概念:用于指示编译器不对变量进行优化(带入上述代码再试一试即可)

volatile const int a = 10;//表示不会对a进行优化

结论:const_cast和reinterpret_cast都是强制类型转换(const_cast的第一个例子中的a去掉const修饰也能const_cast也能正常使用,且a打印时也为20),但是单独将const_cast拿出来就是因为可能出现因为编译器对const修饰的变量进行优化而导致的内存可见性

赋值兼容

基本概念:有继承关系的派生类与基类之间所遵循的赋值规则,包括向上和向下转型

  • 向上转型:派生类对象赋值给基类对象(发生切片,切片  != 类型转换)、派生类的指针/引用赋值给基类的指针/引用(通常情况下都支持)(即这两种情况正常情况下都是可以支持的
#include <iostream>
using namespace std;class A
{};class B : public A
{};int main()
{//向上转型B bb;A aa = bb;//派生类对象直接赋值给基类对象,发生切片A* ptr = &bb;//派生类对象的指针可以直接赋值给基类对象的指针B& cc = bb;A& str = cc;//派生类对象的引用可以直接赋值给基类对象的引用return 0;
}
  • 向下转型:基类对象赋值给派生类对象(除非有相关的构造函数、否则即使是强转也转不了)、基类对象的指针/引用赋值给派生类对象的指针/引用(可以通过强转实现,但有越界风险需要得到控制)

//有相应的构造函数才能实现基类对象到派生类对象间的转换
#include <iostream>
using namespace std;class A {
public:int baseData;A() : baseData(0) {}A(int data) : baseData(data) {}
};class B : public A {
public:B() {};// 自定义构造函数,实现基类到派生类的转换B(const A& a) : A(a) {cout << "hello" << endl;}// 自定义赋值运算符,实现基类到派生类的转换B& operator=(const A& a) {cout << "world" << endl;return *this;}
};int main() {A aaa(10);B bbb;bbb = aaa;  // 使用自定义赋值运算符B bbb2 = aaa;  // 使用自定义构造函数return 0;
}

dynamic_cast

基本概念:为了能控制向下转型时的越界问题、C++提供了dynamic_cast类型转换操作符,dynamic_cast会在转换前检查是否能转换成功,可以转换就转换、不能转换就返回0

#include <iostream>
using namespace std;class A
{
public:virtual void f() {}int _a = 0;
};class B : public A
{
public:int _b = 1;
};void fun(A* pa)
{// 向下转换:父->子// pa指向子类对象,转回子类,是安全的// pa指向父类对象,转回子类,是不安全的,存在越界的风险问题// 不安全//B* pb = (B*)pa;//  pa指向子类对象,转回子类,正常转换//  pa指向父类对象,转回子类,转换失败B* pb = dynamic_cast<B*>(pa);if (pb){cout << pb << endl;cout << pb->_a << endl;cout << pb->_b << endl;}else{cout << "转换失败" << endl;}
}int main()
{A a;B b;fun(&a);//父类转为子类fun(&b);//子类转为子类return 0;
}

注意事项:dynamic_cast在使用时,基类要有虚函数(有就行)

~over~

相关文章:

C++中的类型转换操作符:static_cast reinterpret_cast const_cast dynamic_cast

目录​​​​​​​ C语言中的类型转换 C中的类型转换 C中的类型转换操作符 static_cast reinterpret_cast const_cast volatile关键字 赋值兼容 dynamic_cast C语言中的类型转换 基本概念&#xff1a;赋值运算符左右两侧类型不同&#xff0c;或形参与实参类型不匹配…...

MySQL-SQL优化Explain命令以及参数详解

前言 在MySQL优化的众多手段中&#xff0c;EXPLAIN命令扮演着至关重要的角色。它是数据库管理员和开发者手中的利器&#xff0c;用于分析SQL查询的执行计划。通过执行EXPLAIN&#xff0c;MySQL会提供一份详细的查询执行计划报告&#xff0c;这份报告揭示了查询将如何执行&…...

别只会重启了!进来告诉你AP无法上线怎么办

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 你们好&#xff0c;我的网工朋友。 作为网工&#xff0c;咱们都知道无线网络的重要性&#xff0c;尤其是对于企业网络来说&#xff0c;无线接入点…...

数据恢复篇:如何在 Android 手机上恢复未保存/删除的 Word 文档

在 Android 手机上访问 Word 文档通常很简单&#xff0c;但是当这些重要文件被删除或未保存时会发生什么&#xff1f;这种情况虽然令人痛苦&#xff0c;但并非毫无希望。到 2024 年&#xff0c;有几种强大的方法来处理此类数据丢失。本指南重点介绍如何在Android手机上恢复已删…...

Python | Leetcode Python题解之第208题实现Trie(前缀树)

题目&#xff1a; 题解&#xff1a; class Trie:def __init__(self):self.children [None] * 26self.isEnd Falsedef searchPrefix(self, prefix: str) -> "Trie":node selffor ch in prefix:ch ord(ch) - ord("a")if not node.children[ch]:retur…...

Ethernet是以太网通讯

...

咖啡消费旺季到来 为何想转让的库迪联营商却越来越多

文 | 智能相对论 作者 | 霖霖 去年还在朝“三年万店”计划狂奔的库迪&#xff0c;今年已出现明显“失速”。 早在今年2月&#xff0c;库迪就官宣其门店数已超过7000家&#xff0c;如今4个多月过去&#xff0c;据极海品牌监测数据显示&#xff0c;截至6月27日&#xff0c;其总…...

神经网络原理

神经网络原理是一种模拟人脑的机器学习技术&#xff0c;通过大量的神经元和层次化的连接进行信息处理和学习。 图1 神经元 神经网络由许多简单的计算单元或“神经元”组成&#xff0c;这些神经元通过连接传递信息。每个连接都有一个权重&#xff0c;用于调整传递的信号强度。这…...

安卓应用开发学习:获取经纬度及地理位置描述信息

前段时间&#xff0c;我在学习鸿蒙应用开发的过程中&#xff0c;在鸿蒙系统的手机上实现了获取经纬度及地理位置描述信息&#xff08;鸿蒙应用开发学习&#xff1a;手机位置信息进阶&#xff0c;从经纬度数据获取地理位置描述信息&#xff09;。反而学习时间更长的安卓应用开发…...

各类排序方法 手撕快排 回顾经典快排 优化版快排

快排的主要思想是分而治之 第一步&#xff0c;确定分界点&#xff0c;a 第二步&#xff0c;调整区间&#xff0c;利用分界点a&#xff0c;把小于分界点a的数放在左边&#xff0c;大于的放在右边&#xff0c;相等的放在哪都可以 第三步&#xff0c;递归处理左右两段 实现(暴…...

独一无二的设计模式——单例模式(Java实现)

1. 引言 亲爱的读者们&#xff0c;欢迎来到我们的设计模式专题&#xff0c;今天的讲解的设计模式&#xff0c;还是单例模式哦&#xff01;上次讲解的单例模式是基于Python实现&#xff08;独一无二的设计模式——单例模式&#xff08;python实现&#xff09;&#xff09;的&am…...

使用MoA(Mixture of Agents)混合智能体技术,结合多个开源大语言模型如Llama3、phi-3和Mistral,实现一个强大的AI智能体

1.简介 论文简介: 论文提出了一种称为混合智能体(Mixture-of-Agents,MoA)的方法,利用多个大语言模型(LLM)的集体智慧来提高自然语言理解和生成任务的性能。 MoA采用了分层结构,每一层包含多个LLM智能体。每个智能体都将前一层所有智能体的输出作为辅助信息来生成自己的回答。通…...

前端面试题_Css

一、说一下Css的盒子模型&#xff1f; HTML中所有元素都可以看成是一个盒子 盒子的组成&#xff1a;content、padding、border、margin 盒子的类型&#xff1a; 标准盒模型&#xff1a;marginborderpaddingcontent -- box-sizing&#xff1a;content-box&#xff08;默认&a…...

AI在线免费视频工具3:声音生视频

1、声音生视频 Noisee&#xff1a;通过声音生成对应视频&#xff0c;可以增加prompt指定生成内容相关视频 https://noisee.ai/create...

final、const、readonly关键字在不同语言中代表着什么

一、Java 1.被final修饰的类不能被继承。 2.被final修饰的方法不能被重写。 被 final 修饰的类中所有的成员方法都会隐式的定义为 final 方法。 若父类中 final 方法的访问权限为 private &#xff0c;则子类中不能直接继承该方法。此时可以在子类中定义相同方法名的函数&…...

HarmonyOS ArkUi Tabs+TabContent+List实现tab吸顶功能

Demo效果 Entry Component struct StickyNestedScroll {State message: string Hello WorldState arr: number[] []scroller new Scroller()StyleslistCard() {.backgroundColor(Color.White).height(72).width("100%").borderRadius(12)}build() {Scroll(this.sc…...

Hugging Face Accelerate 两个后端的故事:FSDP 与 DeepSpeed

社区中有两个流行的零冗余优化器 (Zero Redundancy Optimizer&#xff0c;ZeRO)算法实现&#xff0c;一个来自DeepSpeed&#xff0c;另一个来自PyTorch。Hugging FaceAccelerate对这两者都进行了集成并通过接口暴露出来&#xff0c;以供最终用户在训练/微调模型时自主选择其中之…...

TextField是用于在用户界面中输入文本的控件。它广泛应用于表单、搜索框、评论区等需要用户输入文字的场景

TextField是用于在用户界面中输入文本的控件。它广泛应用于表单、搜索框、评论区等需要用户输入文字的场景。以下是对TextField的详细解释&#xff0c;涵盖其各个方面的功能和属性。 基本属性 text 描述&#xff1a;TextField中当前显示的文本。用法&#xff1a;text: "示…...

MYSQL 四、mysql进阶 5(InnoDB数据存储结构)

一、数据库的存储结构&#xff1a;页 索引结构给我们提供了高效的索引方式&#xff0c;不过索引信息以及数据记录都是保存在文件上的&#xff0c;确切说时存储在页结构中&#xff0c;另一方面&#xff0c;索引是在存储引擎中实现的&#xff0c;Mysql服务器上的存储引擎负责对表…...

Spring企业开发核心框架-下

五、Spring AOP面向切面编程 1、场景设定和问题复现 ①准备AOP项目 项目名&#xff1a;Spring-aop-annotation ②声明接口 /*** - * / 运算的标准接口!*/ public interface Calculator { int add(int i, int j); int sub(int i, int j); int mul(int i, in…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...

构建Docker镜像的Dockerfile文件详解

文章目录 前言Dockerfile 案例docker build1. 基本构建2. 指定 Dockerfile 路径3. 设置构建时变量4. 不使用缓存5. 删除中间容器6. 拉取最新基础镜像7. 静默输出完整示例 docker runDockerFile 入门syntax指定构造器FROM基础镜像RUN命令注释COPY复制ENV设置环境变量EXPOSE暴露端…...

多模态大语言模型arxiv论文略读(112)

Assessing Modality Bias in Video Question Answering Benchmarks with Multimodal Large Language Models ➡️ 论文标题&#xff1a;Assessing Modality Bias in Video Question Answering Benchmarks with Multimodal Large Language Models ➡️ 论文作者&#xff1a;Jea…...

结合PDE反应扩散方程与物理信息神经网络(PINN)进行稀疏数据预测的技术方案

以下是一个结合PDE反应扩散方程与物理信息神经网络(PINN)进行稀疏数据预测的技术方案,包含完整数学推导、PyTorch/TensorFlow双框架实现代码及对比实验分析。 基于PINN的反应扩散方程稀疏数据预测与大规模数据泛化能力研究 1. 问题定义与数学模型 1.1 反应扩散方程 考虑标…...

Android多媒体——音/视频数据播放(十八)

在媒体数据完成解码并准备好之后,播放流程便进入了最终的呈现阶段。为了确保音视频内容能够顺利输出,系统需要首先对相应的播放设备进行初始化。只有在设备初始化成功后,才能真正开始音视频的同步渲染与播放。这一过程不仅影响播放的启动速度,也直接关系到播放的稳定性和用…...