17.C++类型转换

1. C语言中的类型转换

        在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转换,C语言中共有两种形式的类型转换:隐式类型转换和显式类型转换。

1.隐式类型转换:编译器在编译阶段自动进行,能转就转,不能转就编译失败

2.显时类型转换:需要用户自己处理

缺陷:转换的可视性较差,所有的转换类型都是用一种相同的形式书写,难以跟踪错误的转换。


2. 为什么C++需要四种类型转换

 解决C风格类型转换的缺陷

C语言中的类型转换存在以下问题:

  • 缺乏安全性检查:如父类指针强制转换为子类指针时,可能指向非子类对象,导致内存越界。
  • 语义模糊:所有转换都用同一语法(如(int*)),难以区分不同场景(如常量性修改、类层次转换等),代码可读性差。
  • 隐式风险:例如将const指针转为非const指针,可能导致未定义行为,但编译器不会警告。

C++要兼容C语言,所以C++还可以使用C语言的转换风格。

3. C++强制类型转换

通过四种专用操作符,限制转换场景并引入安全检查:

  • static_cast:用于安全的隐式转换(如基本类型转换、类层次上行转换),禁止无关类型转换(如int*double*)。
  • dynamic_cast:在类层次下行转换时进行运行时类型检查(需父类有虚函数),失败返回nullptr或抛出异常,避免非法访问。
  • const_cast:明确用于修改constvolatile属性,避免意外修改常量对象。
  • reinterpret_cast:低级别位模式转换(如指针转整数),明确标识高风险操作。

3.1 static_cast

基本类型转换

double d = 3.14;
int i = static_cast<int>(d);  // 显式截断小数部分 

编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换

以下类型被视为相关类型(Related Types),可安全使用static_cast

  • 同一继承链的类(基类↔派生类)
  • 基本数值类型互转(如intdoublefloatlong
  • 用户定义转换支持的类型(通过构造函数或operator重载)
  • void*与其他对象指针(需显式指明目标类型)

什么叫不相关的类型

  • 无继承关系:不在同一个类层次结构中(非基类与派生类)。
  • 无标准转换规则支持:无法通过隐式转换或用户定义的转换函数建立联系。
  • 内存布局不兼容:类型的大小、对齐方式或二进制表示差异较大。
class A {};
class B {};A* a = new A();
// B* b = static_cast<B*>(a);  // 编译错误:A与B无继承关系 int x = 10;
int* p = &x;
// double* dp = static_cast<double*>(p);  // 编译错误:int*与double*无关联 struct Vec3 { float x, y, z; };
// int n = static_cast<int>(Vec3{1,2,3});  // 编译错误:无用户定义的转换规则 

3.2 reinterpret_cast

用于将一种类型转换成另一种不同的类型:

int* p = new int(42);
uintptr_t addr = reinterpret_cast<uintptr_t>(p);  // 地址转整数 

3.3 const_cast

最常用的用途就是删除变量的const属性,方便赋值

const int x = 10;
int* px = const_cast<int*>(&x);  // 语法允许 
*px = 20;                        // 未定义行为!x可能存储在只读内存 

3.4 dynamic_cast

用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)

dynamic_cast 是 C++ 中**唯一依赖运行时类型信息(RTTI)的类型转换操作符,专用于处理 类层次结构中的多态类型安全转换。其核心逻辑为:

  1. 运行时类型检查:通过查询对象的虚函数表(vtable)获取实际类型信息,验证目标类型是否与对象真实类型兼容。
  2. 安全失败机制:若转换不合法(如父类对象并非目标子类实例),指针转换返回 nullptr,引用转换抛出 std::bad_cast 异常。
  3. 多态性依赖:要求基类至少有一个虚函数(否则无法生成虚表,编译报错)。
class Animal { 
public:virtual ~Animal() {}  // 必须至少有一个虚函数 
};
class Dog : public Animal { 
public: void bark() { /* 子类特有方法 */ } 
};Animal* animal = new Dog();  // 多态指针 
Dog* dog = dynamic_cast<Dog*>(animal);  // 合法:animal实际指向Dog对象 
if (dog) dog->bark();  // 安全调用子类方法 
class A { virtual ~A() {} };
class B : public A {};
class C : public A {};A* obj = new B();
C* c = dynamic_cast<C*>(obj);  // 返回nullptr,因obj实际是B类型 

A类对象obj并非C类实例,而是B类实例

转换类型典型场景安全检查性能开销使用频率
static_cast类型关联明确的转换编译期检查⭐⭐⭐⭐
dynamic_cast多态类型下行转换运行时检查较高⭐⭐
const_cast常量性/易变性修改
reinterpret_cast底层内存重解释

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

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

相关文章

springboot志同道合交友网站设计与实现(代码+数据库+LW)

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本志同道合交友网站就是在这样的大环境下诞生&#xff0c;其可以帮助使用者在短时间内处理完毕庞大的数据信…

VMware中的linux常用指令

常用 Linux 基础命令 文件与目录操作 ls&#xff1a;查看当前目录的文件和子目录&#xff0c;ls -a显示所有文件&#xff0c;包括隐藏文件。cd&#xff1a;切换目录&#xff0c;如 **cd ~** 切换到个人家目录。pwd&#xff1a;查看当前目录。mkdir&#xff1a;创建文件夹&#…

20250212:https通信

1:防止DNS劫持:使用 https 进行通信。 因为是SDK授权开发,需要尽量压缩so库文件和三方依赖。所以第一想法是使用 head only 的 cpp-httplib 进行开发。 cpp-httplib 需要 SSL 版本是 3.0及以上。但本地已经在开发使用的是1.0.2a版本,不满足需求。 方案1:升级OpenSSL 将Op…

VisionPro-PMA工具

VisionPro-PMA工具 模板匹配的核心概念 康耐视(Cognex)的VisionPro是一款广泛应用工业自动化的机器视觉软件平台&#xff0c;其模板匹配(Pattern Matching)功能是核心工具之一&#xff0c;常用与目标定位、特征识别和质量检测等场景。 模板匹配&#xff1a;通过预先定义的参…

2025最新最全【大模型学习路线规划】零基础入门到精通_大模型 开发 学习路线

第一阶段&#xff1a;基础理论入门 目标&#xff1a;了解大模型的基本概念和背景。 内容&#xff1a; 人工智能演进与大模型兴起。 大模型定义及通用人工智能定义。 GPT模型的发展历程。 第二阶段&#xff1a;核心技术解析 目标&#xff1a;深入学习大模型的关键技术和工…

使用CSS3DRenderer/CSS2DRenderer给模型上面添加html标签

先放一下预览图 主要使用css2dRender和css3dRender&#xff0c;添加图片和标签。 思路&#xff1a;使用css3dRender添加一个图片&#xff0c;然后获取的位置坐标&#xff0c;使用css3dRender添加一个文字标签&#xff0c;也设置这个位置坐标&#xff0c;此外z轴设置一个高度&a…

完美隐藏滚动条方案 (2024 最新验证)

完美隐藏滚动条方案 (2024 最新验证) css /* 全局隐藏竖直滚动条但保留滚动功能 */ html {overflow: -moz-scrollbars-none; /* Firefox 旧版 */scrollbar-width: none; /* Firefox 64 */-ms-overflow-style: none; /* IE/Edge */overflow-y: overlay; …

Linux 内核配置机制详细讲解

本文是对 Linux 内核配置机制 make menuconfig 的 超详细分步解析&#xff0c;涵盖其工作原理、界面操作、配置逻辑及底层实现&#xff1a; 一、内核配置系统概述 Linux 内核的配置系统是一个 基于文本的交互式配置工具链&#xff0c;核心目标是通过定义 CONFIG_XXX 宏来控制内…

视频裂变加群推广分享引流源码

源码介绍 视频裂变加群推广分享引流源码 最近网上很火&#xff0c;很多人都在用&#xff0c;适合引流裂变推广 测试环境&#xff1a;PHP7.4(PHP版本不限制) 第一次访问送五次观看次数&#xff0c;用户达到观看次数后需要分享给好友或者群,好友必须点击推广链接后才会增加观看次…

python-leetcode-每日温度

739. 每日温度 - 力扣&#xff08;LeetCode&#xff09; class Solution:def dailyTemperatures(self, temperatures: List[int]) -> List[int]:n len(temperatures)answer [0] * nstack [] # 存储索引for i, temp in enumerate(temperatures):while stack and temperat…

文件下载技术的终极选择:`<a>` 标签 vs File Saver.js

文件下载技术的终极选择&#xff1a;<a> 标签 vs File Saver.js 在 Web 开发中&#xff0c;文件下载看似简单&#xff0c;实则暗藏玄机。工作种常纠结于 <a> 标签的原生下载和 File Saver.js 等插件的灵活控制之间。本文将从原理、优缺点、场景对比到实战技巧&…

deepseek sse流式输出

链接 semi-ui-vue聊天组件 - 可以用这个组件优化界面 sse服务端消息推送 webflux&webclient Hi-Dream-Blog - 参考这个博客&#xff0c;可以在后台将markdown语法转为html 文章目录 链接效果代码pom.xmlDeepSeekControllerWebConfigDeepSeekClientAiChatRequestAiChatM…

Linux时间日期类指令

1、data指令 基本语法&#xff1a; date &#xff1a; 显示当前时间date %Y : 显示当前年份date %m &#xff1a; 显示当前月份date %d &#xff1a; 显示当前哪一天date “%Y-%m-%d %H:%M:%S" &#xff1a; 显示年月日时分秒date -s 字符串时间 &#xff1a; 设置系统时…

SQLMesh 系列教程9- 宏变量及内置宏变量

SQLMesh 的宏变量是一个强大的工具&#xff0c;能够显著提高 SQL 模型的动态化能力和可维护性。通过合理使用宏变量&#xff0c;可以实现动态时间范围、多环境配置、参数化查询等功能&#xff0c;从而简化数据模型的开发和维护流程。随着数据团队的规模扩大和业务复杂度的增加&…

鹏哥c语言数组(初阶数组)

前言&#xff1a; 对应c语言视频54集 内容&#xff1a; 一维数组的创建 数组是一组相同元素的集合&#xff0c; 数组的创建方式 type_t就是数组的元素类型&#xff0c;const_n是一个常量表达式&#xff0c;用来指定数组的大小 c99标准之前的&#xff0c;数组的大小必须是…

爬虫运行后如何保存数据?

爬虫运行后&#xff0c;将获取到的数据保存到本地或数据库中是常见的需求。Python 提供了多种方式来保存数据&#xff0c;包括保存为文本文件、CSV 文件、JSON 文件&#xff0c;甚至存储到数据库中。以下是几种常见的数据保存方法&#xff0c;以及对应的代码示例。 1. 保存为文…

计算机视觉:经典数据格式(VOC、YOLO、COCO)解析与转换(附代码)

第一章&#xff1a;计算机视觉中图像的基础认知 第二章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(一) 第三章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(二) 第四章&#xff1a;搭建一个经典的LeNet5神经网络(附代码) 第五章&#xff1…

linux--多进程基础(2)GDB多进程调试(面试会问)

将其中的命令记住就行。 总结&#xff1a;GDB下默认调试父进程&#xff0c;可以设置调试父进程还是子进程&#xff0c;也可以设置调试模式&#xff0c;调试模式默认是on即一个在调试另一个直接运行&#xff0c;off就是另一个进程挂起&#xff0c;最后可以查看调试进程 一般默认…

Cramér-Rao界:参数估计精度的“理论底线”

Cramr-Rao界&#xff1a;参数估计精度的“理论底线” 在统计学中&#xff0c;当我们用数据估计一个模型的参数时&#xff0c;总希望估计结果尽可能精确。但精度有没有一个理论上的“底线”呢&#xff1f;答案是有的&#xff0c;这就是Cramr-Rao界&#xff08;Cramr-Rao Lower …

【复习】Redis

数据结构 Redis常见的数据结构 String&#xff1a;缓存对象Hash&#xff1a;缓存对象、购物车List&#xff1a;消息队列Set&#xff1a;点赞、共同关注ZSet&#xff1a;排序 Zset底层&#xff1f; Zset底层的数据结构是由压缩链表或跳表实现的 如果有序集合的元素 < 12…