【C++】explicit关键字详解(explicit关键字是什么? 为什么需要explicit关键字? 如何使用explicit 关键字)

目录

一、前言

二、explicit关键字是什么? 

 三、构造函数还具有类型转换的作用

 🍎单参构造函数

✨引出 explicit 关键字 

 🍍多参构造函数

✨为什么需要explicit关键字? 

✨怎么使用explicit关键字?

四、总结 

 五、共勉


一、前言

        在我们自己平时写 C++ 代码的时候,较少会用到 explicit关键字 。但是在C++相关的标准类库中,看到explicit关键字的频率还是很高的。既然出现的频率这么高,那么我们就来看看explicit关键字的作用到底是干什么的。

二、explicit关键字是什么? 

        explicit是C++中的一个关键字,它用来修饰只有一个参数的类构造函数,以表明该构造函数是显式的,而非隐式的。当使用explicit修饰构造函数时,它将禁止类对象之间的隐式转换,以及禁止隐式调用拷贝构造函数。 
       这能这么说,大家不太好理解,既然解释中提到了 类的构造函数  那么下面我将从构造函数中详细的给大家,讲解explicit其中的含义。

 三、构造函数还具有类型转换的作用

        在理解 explicit 关键字 之前,我们必须要了解构造函数的类型转换作用,以便于我们更好的理解 explicit 关键字 ,如果有不懂构造函数的老铁,可以来看看这篇文章:构造函数

 🍎单参构造函数

还是来说说老朋友日期类,我们通过下面这个日期类进行讲解

class Date
{
public:
// 构造函数Date(int year):_year(year)    // 初始化列表{}private:int _year;int _month = 3;int _day = 31;
};
  • 对于下面的 d1 很清楚一定是调用了有参构造进行初始化,不过对于 d2 来说,也是一种构造方式
int main()
{// d1 和 d2 都会调用构造函数Date d1(2022);   Date d2 = 2023;return 0;
}
  •  我们依旧通过调试来看就会非常清晰,这种 【Date d2 = 2023】 写法也会去调用构造函数

      此时,大家可能会产生疑问,这种构造方式从来没有见过,为什么 【Date d2 = 2023】会调用 构造函数呢?  其实这都是因为有【隐式类型转换】的存在,下面我将从一个简单的例子来为大家讲解。

  • 在引用详解,我有提到过【隐式类型转换】这个概念,像下面将一个int类型的数值赋值给到一个double类型的数据,此时就会产生一个隐式类型转换
int i = 1;
double d = i;
  • 对于类型转换而言,这里并不是将值直接赋值给到左边的对象,而是在中间呢会产生一个临时变量,例如右边的这个 i 会先去构造一个临时变量,这个临时变量的类型是 [double] 。把它里面的值初始化为 1,然后再通过这个临时对象进行拷贝构造给d,这就是编译器会做的一件事

  • 那对于这个 d2 其实也是一样,2023会先去构造一个临时对象,这个临时对象的类型是[Date]把它里面的year初始化为2023,然后再通过这个临时对象进行拷贝构造给到d2

 💬小蛋:不是说构造函数有初始化列表吗?拷贝构造怎么去初始化呢?

//拷贝构造
Date(const Date& d):_year(d._year),_month(d._month),_day(d._day)
{}
  •   同学,别忘了【拷贝构造】也是属于构造函数的一种哦,也是会有初始化列表的

 刚才说到了中间会产生一个临时对象,而且会调用构造 + 拷贝构造,那此时我们在Date类中写一个拷贝构造函数,调试再去看看会不会去进行调用

  • 很明显没有,我在进入Date类后一直在按F11,但是却进不到拷贝构造中,这是为什么呢?

  •  原因其实在于编译器在这里地方做了一个优化,将【构造 + 拷贝构造】优化成了【一个构造】,因为编译器在这里觉得构造再加拷贝构造太费事了,干脆就合二为一了。其实对于这里的优化不同编译器是有区别的,像一下VC++、DevC++可能就不会去优化,越是新的编译器越可能去进行这种优化。在本文的最后一个模块我还会详细展开分析

💬小蛋:但您是怎么知道中间赋值这一块产生了临时对象呢?如果不清楚编译器的优化机制这一块肯定就会认为这里只有一个构造 

  • 这点确实是,若是我现在不是直接赋值了,而是去做一个引用,此时会发生什么呢?
Date& d3 = 2024;
  • 可以看到,报出了一个错误,原因就在于d3是一个Date类型,2024则是一个内置类型的数据

  • 但若是我在前面加一个const做修饰后,就不会出现问题了,这是为什么呢?
  • 其实这里的真正原因就在于产生的这个【临时变量】(临时变量具有常性),它就是通过Date类的构造函数构造出来的,同类型之间可以做引用。还有一点就是临时变量具有常性,所以给到一个const类型修饰对象不会有问题 

引出 explicit 关键字 

        但若是你不想让这种隐式类型转换发生怎么办呢?此时就可以使用到C++中的一个关键字叫做explicit 

  • 它加在构造函数的前面进行修饰,有了它就不会发生上面的这一系列事儿了,它会【禁止类型转换】
explicit Date(int year):_year(year)
{}

 🍍多参构造函数

对于上面所讲的都是基于单参的构造函数,接下去我们来瞧瞧多参的构造函数 

//多参构造函数
Date(int year, int month ,int day = 31):_year(year),_month(month),_day(day)
{}
  • 根据从右往左缺省的规则,我们在初始化构造的时候要给到2个参数,d1没有问题传入了两个参数,但是若是像上面那样沿袭单参构造函数这么去初始化还行得通吗?很明显不行,编译器报出了错误

 💬小蛋:那要怎么办呀,对于一定要传入多参数进行构造的场景

  •  这个时候就要使用到我们C++11中的新特性了,在对多参构造进行初始化的时候在外面加上一个{}就可以了,可能你觉得这种写法像是C语言里面结构体的初始化,但实际不是,而是在调用多参构造函数
Date d2 = { 2023, 3 };

  • 不仅如此,对于下面这种也同样适用,调用构造去产生一个临时对象
const Date& d3 = { 2024, 4 };

 那要如何去防止这样的隐式类型转换发生呢,还是可以使用到explicit关键字吗?

//多参构造函数
explicit Date(int year, int month ,int day = 31):_year(year),_month(month),_day(day)
{}
  • 可以看到,加上explicit关键字做修饰,同样可以起到【禁止类型转换】的作用

  • 还有一种例外,当缺省参数从右往左给到两个的时候,此时只需要传入一个实参即可,那也就相当于是单参构造explicit关键字依旧可以起到作用·
explicit Date(int year, int month = 3,int day = 31):_year(year),_month(month),_day(day)
{}

✨为什么需要explicit关键字? 

所以对于可读性不是很好的代码,可以使用explicit修饰构造函数,将会禁止构造函数的隐式转换 

✨ 怎么使用explicit关键字?

         explicit关键字在C++中只能用于修饰类的构造函数,它用来修饰只有一个参数的类构造函数,以表明该构造函数是显式的,而非隐式的。

        只要在构造函数名前加上explicit就能禁止类对象之间的隐式转换、禁止隐式调用拷贝构造函数。

四、总结 

 五、共勉

  以下就是我对C++ explicit关键字的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++ 的理解请持续关注我哦!!!

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

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

相关文章

Angular学习第四天--问题记录及父子组件问题

问题一、 拉取完项目,使用npm install命令的时候遇到的。 解决办法: 在查找网上五花八门的解决方案之后,发现都不能解决。 我的解决办法是: 1. 把package-lock.json给删掉; 2. 把package.json中公司自己库的包给删除掉…

C# Solidworks二次开发:模型中实体Entity相关操作API详解

大家好,今天要讲的一些API是关于实体的相关API。 在开发的过程,很多地方会涉及到实体的相关操作,比如通过实体选中节点。下面就直接开始介绍API: (1)第一个API为Select4,这个API的含义为选中一…

Docker 学习笔记(五):梳理 Docker 镜像知识,附带 Commit 方式提交镜像副本,安装可视化面板 portainer

一、前言 记录时间 [2024-4-10] 前置文章: Docker学习笔记(一):入门篇,Docker概述、基本组成等,对Docker有一个初步的认识 Docker学习笔记(二):在Linux中部署Docker&…

FluentUI系列 - 1 - 介绍第一个窗口

介绍一个QML的UI库,国人编写,作者也耍知乎。这个UI库确实好用,但是教程基本等于无,个人在使用中顺便记录一下学习内容。这玩意儿也有Pyside6的版本,有需要的可以查看PySide6-FluentUI-QML。 FluentUI库地址​github.c…

00 【哈工大_操作系统】Bochs 汇编级调试方法及指令

本文将介绍一下哈工大李治军老师《操作系统》课程在完成Lab时所使用到的 Bochs 调试工具的使用方法。这是一款汇编级调试工具,打开调试模式非常简单,只需在终端下输入如下指令: 1、bochs 调试基本指令大全 功能指令举例在某物理地址设置断点…

bpftime(为什么要有,介绍,原理图),如何编译运行其代码,示例代码(运行结果+解释+内核层代码,用户层代码分析)

目录 bpftime(开源用户态 eBPF 运行时) 引入 在内核态实现用户态追踪的性能损失 内核空间执行ebpf的弊端 内核态 -> 用户态 介绍 原理图 示例代码 如何编译和运行 编译 运行 运行结果 运行结果 代码分析 .c 源码 语法 #include "malloc.skel.h&…

EPSON开发新IMU产品M-G370PDS改善姿态和震动控制

爱普生IMU于2011年首次推出,已在一系列客户应用中使用,因其出色的性能和质量而享有盛誉。近年来,IMU的使用已经扩展到无人系统测量、航空和水下视频摄影等领域。对更准确的位置和姿态控制的需求不断增长,不仅如此,高效…

【小程序】生成短信中可点击的链接

文章目录 前言一、如何生成链接二、仔细拜读小程序开发文档文档说明1文档说明2 总结 前言 由于线上运营需求,需要给用户发送炮轰短信,用户通过短信点击链接直接跳转进入小程序 一、如何生成链接 先是找了一些三方的,生成的倒是快速&#xf…

DDoS攻击类型与应对措施详解

攻击与防御简介 SYN Flood攻击 原理: SYN Flood攻击利用的是TCP协议的三次握手机制。在正常的TCP连接建立过程中,客户端发送一个SYN(同步序列编号)报文给服务器,服务器回应一个SYN-ACK(同步和确认&#xf…

微信小程序wx.getLocation 真机调试不出现隐私弹窗

在小程序的开发过程中,首页中包含要获取用户地理位置的功能,所以在这里的onLoad()中调用了wx.getLocation(),模拟调试时一切正常,但到了真机环境中就隐私框就不再弹出,并且出现了报错&#xff0…

开源相机管理库Aravis例程学习(一)——单帧采集single-acquisition

开源相机管理库Aravis例程学习(一)——单帧采集single-acquisition 简介源码函数说明arv_camera_newarv_camera_acquisitionarv_camera_get_model_namearv_buffer_get_image_widtharv_buffer_get_image_height 简介 本文针对官方例程中的第一个例程&…

maven引入外部jar包

将jar包放入文件夹lib包中 pom文件 <dependency><groupId>com.jyx</groupId><artifactId>Spring-xxl</artifactId><version>1.0-SNAPSHOT</version><scope>system</scope><systemPath>${project.basedir}/lib/Spr…

三款好用的 Docker 可视化管理工具

文章目录 1、Docker Desktop1.1、介绍1.2、下载地址1.3、在Windows上安装Docker桌面1.4、启动Docker Desktop1.5、Docker相关学习网址 2、Portainer2.1、介绍2.2、安装使用 3、Docker UI3.1、介绍3.2、安装使用3.2.1、常规方式安装3.2.2、通过容器安装 Docker提供了命令行工具&…

图深度学习(一):介绍与概念

目录 一、介绍 二、图的数据结构 三、图深度学习的基本模型 四、图深度学习的基本操作和概念 五、训练过程 六、主要应用场景 七、总结 一、介绍 图深度学习是将深度学习应用于图形数据结构的领域&#xff0c;它结合了图论的概念和深度学习的技术&#xff0c;用以处理和…

第二证券今日投资参考:铜价持续上涨 医药政策向好态势明显

昨日&#xff0c;A股在金融板块的带动下强势拉升&#xff0c;沪指涨超1%。到收盘&#xff0c;沪指涨1.26%报3057.38点&#xff0c;深证成指涨1.53%报9369.7点&#xff0c;创业板指涨1.85%报1795.52点&#xff0c;上证50指数涨2.1%&#xff1b;两市合计成交9971亿元&#xff0c;…

5.2 mybatis之autoMappingBehavior作用

文章目录 1. NONE关闭自动映射2. PARTIAL非嵌套结果映射3. FULL全自动映射 众所周知mybatis中标签< resultMap >是用来处理数据库库字段与java对象属性映射的。通常java对象属性&#xff08;驼峰格式&#xff09;与数据库表字段&#xff08;下划线形式&#xff09;是一 一…

分布式文件系统HDFS-2

文章目录 主要内容一.HDFS1.数据错误与恢复2.名称节点出错3.数据节点出错4.数据出错5.HDFS读写过程 6.写操作7.读操作8.读写数据过程 总结 主要内容 分布式文件系统HDFS 一.HDFS 1.数据错误与恢复 HDFS具有较高的容错性&#xff0c;可以兼容廉价的硬件&#xff0c;它把硬件出…

【Qt 学习笔记】Qt常用控件 | 按钮类控件Push Button的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 按钮类控件Push Button的使用及说明 文章编号&#xff1…

Redis中的订阅发布(三)

订阅发布 发送消息 当一个Redis客户端执行PUBLISH 命令将消息message发送给频道channel的时候&#xff0c;服务器需要执行以下 两个动作: 1.将消息message发送给channel频道的所有订阅者2.如果一个或多个模式pattern与频道channel相匹配&#xff0c;那么将消息message发送给…

Open3D (C++) 点云投影至主成分空间

目录 一、算法原理二、代码实现三、结果展示四、相关连接Open3D (C++) 点云投影至主成分空间由CSDN点云侠原创,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 p r o j