C++类型转换详解

目录

一、内置 转 内置

二、内置 转 自定义

三、自定义 转 内置

四、自定义 转 自定义

五、类型转换规范化

1.static_case

2.reinterpret_cast

3.const_cast

4.dynamic_cast

六、RTTI


一、内置 转 内置

        C++兼容C语言,在内置类型之间转换规则和C语言一样的,C/C++语言因为允许类型转换所以不是类型安全的语言。

隐式转化:编译器识别出类型不同后,能转就转,不能转则报错。

例如:

  • int = 'a' 
  • char = 4
  • int = 8.26

除此之外函数调用中形参和实参的类型不同时,编译器会尝试进行隐式转化。

显示转化(强制类型转化):用户进行指定的显示转换。

例如:

  • int = (int)'a' 
  • char = (char)4
  • int = (int)8.26

什么时候能转什么时候不能转呢?

        通常有关联性的类型,有转换意义的类型都是可以转化的。比如int类型与double类型,float类型,short类型等,都是描述数字的大小,又或者各种指针类型之间。

        又比如int与指针不能隐式转换,因为转化后也是无意义的。但可以显示转化(强制类型转化)。

二、内置 转 自定义

        c++中支持内置类型转自定义类型,只需要提供相应的构造函数,就可以想怎么转就怎么转,全在于你的构造函数怎么实现。如下:

using namespace std;
class A
{
public:A(int x):a(x),b(x){}A(int x,int y,int z):a(x), b(y+z){}
private:int a;int b;
};
void fun(A x)
{//......
}
int main()
{int v = 10;A a1 = v;//int类型隐式转化为A类型A a2 = { 1,2,3 };fun(6);return 0;
}
  • A a1 = v:调用构造函数产生临时对象,然后调用拷贝赋值。逻辑上是这样,但实际上会被编译器优化。
  • A a2 = {1,2,3}:通过花括号传入多个参数构造临时对象,然后调用拷贝赋值。
  •  fun(6):在函数传参时,同样会隐式转换,不用单独构造出类型后传入,这样就显得方便得多。

在构造函数的函数名前加关键字explicit:不被允许隐式转换,要进行转换需要显示的进行。

三、自定义 转 内置

        c++中支持自定义类型转内置类型,提供相应的运算符重载函数(operator),同样可以想怎么转就怎么转,都是自己设定的。

        强制类型转化的运算符是(),按理来说应该重载()运算符,但是又与仿函数冲突,所以c++制定了特殊的函数来做类型转化,即:

  • operator 类型 ()

该函数不用写返回类型,但在函数名后面需要加目标类型,函数结束也需要return返回。

class A
{
public:A(int x,int y):_a(x),_b(y){}operator int(){return _a + _b;}
private:int _a;int _b;
};
int main()
{A a1 = { 1,3 };int x = a1;return  0;
}

同样可以使用explicit修饰,修饰后不支持隐式转化。

        比如在c++智能指针shared_ptr中使用了operator bool()把指针转换为bool类型来判断指针是否为空,如下:

测试如下:

#include <iostream>
#include <memory>
using namespace std;
int main()
{shared_ptr<int> p(new int(10));if (!p)//隐式转换为bool类型cout << "p为nullptr";else cout << "p不为nullptr";return 0;
}

四、自定义 转 自定义

        c++中自定义与自定义之间同样可以转换,核心是让构造函数产生临时对象。比如我们要让B类型转换为A类型,我们可以构造这样一个函数:

class A
{
public:A(int x):_a(x),_b(x){}int get_a(){return _a;}
private:int _a;int _b;
};
class B
{
public:B(A x):_val(x.get_a()){}
private:int _val;
};
int main()
{A a = 4;B b = a;return  0;
}

五、类型转换规范化

        C 风格的类型转换过于“暴力”,允许许多不安全的转换。C++提供的 显式类型转换运算符来替代传统的 C 风格强制类型转换(如 (int)x)。这种机制的目的是提高代码的 类型安全性可读性 和 维护性,同时限制不安全的隐式转换。

它有四种类型转换运算符,接下来我们依次来学习。

1.static_case

        用于意义相近的转换,比如int与double,char与int,左值与右值,如下:

int main()
{char ch = 'm';int x = static_cast<int>(ch);return 0;
}

2.reinterpret_cast

        reinterpret_cast用于高风险的类型转换,即意义不相近的类型之间,或各种指针之间的转换,比如int与int*,char*与int*。

int main()
{int x = 10;int* p = reinterpret_cast<int*>(x);return 0;
}

3.const_cast

        const_cast用来添加/移除const属性的类型间转换,或者添加/移除volatile属性的类型间转换,如下:

int main()
{volatile const int n = 10;int* v = const_cast<int*>(&n);//移除const属性const int& m = const_cast<const int&>(m);//移除volatile属性return 0;
}

4.dynamic_cast

用于基类与派生类之间的类型转换。

        派生类转基类也叫切片,天然就可以实现的,但是基类转派生类可能会存在越界访问的问题。用这个关键字可以有效避免。

class Base { 
public:virtual ~Base() {} 
};
class Derived : public Base {};Base* base_ptr = new Base(); // 基类指针指向基类对象// 尝试向下转型
Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);
if (derived_ptr == nullptr) { // 转换失败!
}

六、RTTI

        RTTI(Runtime Type Information,运行时类型信息) 是 C++ 提供的一种在程序运行时获取对象类型信息的机制。它允许程序在运行时检测对象的实际类型,并支持安全的类型转换(如 dynamic_cast)和类型查询(如 typeid)。

        注意:typeid并不是每次都是运行时类型识别。RTTI依赖多态类型,只有类有虚函数时才能体现 。

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

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

相关文章

QEMU源码全解析 —— 块设备虚拟化(17)

接前一篇文章:QEMU源码全解析 —— 块设备虚拟化(16) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM源码解析与应用》 —— 李强,机械工业出版社 《KVM实战 —— 原理、进阶与性能调优》—— 任永杰 程舟,机械工业出版社

mac 卸载流氓软件安全助手

之前个人电脑在公司使用过一段时间&#xff0c;为了使用网线联网安装了公司指定的 联软上网助手&#xff0c;谁知安装容易卸载难&#xff0c;后来找运维来卸载&#xff0c;输入管理员密码后&#xff0c;也无反应&#xff0c;最后不了了之了&#xff0c;这个毒瘤软件长期在后台驻…

Java 大视界 -- Java 大数据机器学习模型在智能客服多轮对话系统中的优化策略(179)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

极氪汽车云原生架构落地实践

云原生架构落地实践的背景 随着极氪数字业务的飞速发展&#xff0c;背后的 IT 技术也在不断更新迭代。极氪极为重视客户对服务的体验&#xff0c;并将系统稳定性、业务功能的迭代效率、问题的快速定位和解决视为构建核心竞争力的基石。 为快速响应用户的需求&#xff0c;例如…

Python•判断循环

ʕ⸝⸝⸝˙Ⱉ˙ʔ ♡ 判断🍰常用的判断符号(比较运算符)andor括号notin 和 not inif-elif-else循环🍭计数循环 forrange()函数简易倒计时enumerate()函数zip()函数遍历列表遍历元组遍历字符串遍历字典条件循环 while提前跳转 continue跳出循环 break能量站😚判断🍰 …

FreeRTOS与RT-Thread深度对比:从入门到精通的全面解析

FreeRTOS与RT-Thread深度对比&#xff1a;从入门到精通的全面解析 在嵌入式系统开发领域&#xff0c;实时操作系统(RTOS)扮演着至关重要的角色。FreeRTOS和RT-Thread作为两款主流的开源RTOS&#xff0c;各有特色&#xff0c;适用于不同的应用场景。本文将从小白到大神的角度&a…

OpenCV 图形API(18)用于执行两个矩阵(或数组)的逐元素减法操作函数sub()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 描述 计算两个矩阵之间的逐元素差值。 sub 函数计算两个矩阵之间的差值&#xff0c;要求这两个矩阵具有相同的尺寸和通道数&#xff1a; dst ( I ) src…

LeetCode刷题SQL笔记

系列博客目录 文章目录 系列博客目录1.distinct关键字 去除重复2.char_length()3.group by 与 count()连用4.date类型有个函数datediff()5.mod 函数6.join和left join的区别1. **JOIN&#xff08;内连接&#xff0c;INNER JOIN&#xff09;**示例&#xff1a; 2. **LEFT JOIN&a…

其他合成方式介绍

在 SurfaceFlinger 的 Layer 处理逻辑中&#xff0c;除了常见的 Client Composition&#xff08;GPU合成&#xff09; 和 Device Composition&#xff08;HWC合成&#xff09;&#xff0c;还存在一些特殊的合成方式&#xff0c;比如 Sideband、Solid Color 和 Display Decorati…

GraphRAG与知识图谱

一、GraphRAG介绍 1.1 什么是 Graph RAG&#xff1f; Graph RAG&#xff08;Retrieval-Augmented Generation&#xff09;&#xff0c;是一种基于知识图谱的检索增强技术&#xff0c; 通过构建图模型的知识表达&#xff0c;将实体和关系之间的联系用图的形式进行展示&#xff…

一个开源的 VS Code 大模型聊天插件:Light-at

这篇文章是一个开发杂谈。对于有经验的开发者来说&#xff0c;可能这个项目并不算特别复杂或者高技术&#xff0c;只是对我个人来说算一个里程碑&#xff0c;因此写篇杂谈文章记录一下。也许也能给起步者一些参考。 项目地址&#xff1a;https://github.com/HiMeditator/light-…

SQL121 创建索引

-- 普通索引 CREATE INDEX idx_duration ON examination_info(duration);-- 唯一索引 CREATE UNIQUE INDEX uniq_idx_exam_id ON examination_info(exam_id);-- 全文索引 CREATE FULLTEXT INDEX full_idx_tag ON examination_info(tag);描述 现有一张试卷信息表examination_in…

【Pandas】pandas DataFrame set_flags

Pandas2.2 DataFrame Attributes and underlying data 方法描述DataFrame.index用于获取 DataFrame 的行索引DataFrame.columns用于获取 DataFrame 的列标签DataFrame.dtypes用于获取 DataFrame 中每一列的数据类型DataFrame.info([verbose, buf, max_cols, …])用于提供 Dat…

Linux终止进程(kill process)的一些玩法

经常运行一个程序时&#xff0c;表面上已经终止了&#xff0c;实际上还在后台运行。一来呢&#xff0c;它可能占据端口&#xff0c;导致端口复用的时候报错。二来呢&#xff0c;它可能占用GPU&#xff0c;让你显存直接少一块。 尤其是在多进程程序&#xff0c;假如运行“python…

《比特城传奇:公钥、私钥与网络安全的守护之战》

点击下面图片带您领略全新的嵌入式学习路线 &#x1f525;爆款热榜 88万阅读 1.6万收藏 第一章&#xff1a;双钥之谜 比特城的清晨总是笼罩着一层薄雾&#xff0c;仿佛这座城市本身就是由无数个0和1编织而成的幻境。在这里&#xff0c;信息如同空气般无处不在&#xff0c;但…

BGP路由协议之属性1

公认属性是所有 BGP 路由器都必须能够识别的属性 公认必遵 (Well-known Mandatory) : 必须包括在每个 Update 消息里公认任意 (Well-known Discretionary) : 可能包括在某些 Update 消息里。 可选属性不需要都被 BGP 路由器所识别 可选过渡(OptionalTransitive) : BGP 设备不…

Pr视频剪辑 Premiere Pro 2024 for Mac

Pr视频剪辑 Premiere Pro 2024 for Mac 文章目录 Pr视频剪辑 Premiere Pro 2024 for Mac一、介绍二、效果三、下载 一、介绍 Premiere Pro 2024 for Mac是一款专业的视频编辑软件&#xff0c;广泛应用于电影、电视、广告等领域。它为Mac用户提供了强大的剪辑、调色、音频处理等…

oracle 包的管理

在PL/SQL程序开发中&#xff0c;为了方便实现模块化程序的管理&#xff0c;可以将PL/SQL元素&#xff08;如存储过程、函数、变量、常量、自定义数据类型、游标等&#xff09;根据模块的程序结构组织在一起&#xff0c;存放在一个包中&#xff0c;称为一个完整的单元&#xff0…

LINUX 5 cat du head tail wc 计算机拓扑结构 计算机网络 服务器 计算机硬件

计算机网络 计算机拓扑结构 计算机按性能指标分&#xff1a;巨型机、大型机、小型机、微型机。大型机、小型机安全稳定&#xff0c;小型机用于邮件服务器 Unix系统。按用途分&#xff1a;专用机、通用机 计算机网络&#xff1a;局域网‘、广域网 通信协议’ 计算机终端、客户端…

从零开始的图论讲解(1)——图的概念,图的存储,图的遍历与图的拓扑排序

目录 前言 图的概念 1. 顶点和边 2. 图的分类 3. 图的基本性质 图的存储 邻接矩阵存图 邻接表存图 图的基本遍历 拓扑排序 拓扑排序是如何写的呢? 1. 统计每个节点的入度 2. 构建邻接表 3. 将所有入度为 0 的节点加入队列 4. 不断弹出队头节点&#xff0c;更新其…