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

news/2024/10/24 3:23:30/

目录

一、前言

二、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.ppmy.cn/news/1424287.html

相关文章

Codigger GT模块:GUI融合Terminal,重塑开发体验

Codigger GT模块:GUI融合Terminal,重塑开发体验

在信息技术日新月异的今天,开发者与计算机系统进行交互的界面,其体验的优化与升级显得尤为关键。Codigger G&T正是应这一需求而生,它巧妙地将现代图形用户界面(GUI)的优势融入传统的Terminal中,为开发者…
阅读更多...
Setting.xml文件方面问题

Setting.xml文件方面问题

一般选择对应项目的settings.xml文件 以此来通过maven来获得对应配置 下载依赖包等 配置 maven 打开项目的setting.xml文件 看下对应的配置 这个本地仓库地址尽量要跟图一中的Localrepository:中的 地址一致 否则一般运行idea时候 会优先使用xml配置的仓库地址 然后下面…
阅读更多...
Java智慧校园系统源码springboot + vue智慧学校源码 微信小程序+电子班牌

Java智慧校园系统源码springboot + vue智慧学校源码 微信小程序+电子班牌

Java智慧校园系统源码springboot vue智慧学校源码 微信小程序电子班牌 智慧校园的建设逐渐被师生、家长认可接受,智慧校园通过对在校师生、教务等所有人员的信息以及各种信息搜集与储存,进行数据优化与管理,为师生们提供更加智能化的校园服务…
阅读更多...
数据结构从入门到实战——顺序表

数据结构从入门到实战——顺序表

目录 前言 一、顺序表的概念及结构 1.1 线性表 二、顺序表分类 三、动态顺序表的实现 3.1 顺序表结构的创建以及初始化 3.2 顺序表的销毁 3.3 顺序表的打印 3.4 尾插数据 ——最困难的 3.5 头插数据 3.6 尾删数据 3.7 头部删除数据 前言 在计算机科学和数据结…
阅读更多...
如何升级node.js版本

如何升级node.js版本

升级Node.js可以通过多种方式来完成,以下是四种常见的方法: 方法一:使用Node.js官方安装程序 访问Node.js的官方网站,下载对应你操作系统的最新版本安装程序。通常,你可以 https://nodejs.org/en/download 找到你需…
阅读更多...
搭建Maven的Nexus3私服

搭建Maven的Nexus3私服

搭建Maven的Nexus3私服 1、常见的Maven私服产品 Apache的ArchivaJFrog的ArtifactorySonatype的Nexus([ˈneksəs])(当前最流行、使用最广泛) 2. windows java8安装和配置私服Nexus3 参考: https://zhuanlan.zhihu…
阅读更多...
通用航空机场系统架构:连接天空与大地的科技之桥

通用航空机场系统架构:连接天空与大地的科技之桥

在现代航空业的背景下,通用航空机场系统架构的重要性愈发凸显。通用航空机场作为航空运输网络的重要组成部分,承担着连接各地区、支持经济发展和满足民众出行需求的重任。而其系统架构的设计与运作,直接影响着机场的安全性、效率性以及用户体…
阅读更多...
BOOT和UBOOT区别与联系

BOOT和UBOOT区别与联系

一、定义 1.1 Boot(启动) 在计算机和嵌入式系统的基本概念中,“boot”是指启动过程,这是一个系统从加电开始直至进入操作系统运行状态的过程。在嵌入式系统中,这个过程通常包括初始化硬件、加载并执行引导加载…
阅读更多...
最新文章

玻璃钢生产厂家秋季商场美陈现价玻璃钢花盆有哪些好处大型玻璃钢雕塑合作公司玻璃钢烽火台雕塑蚌埠特色玻璃钢雕塑联系方式重庆玻璃钢彩绘雕塑玻璃钢雕塑师电话浙江佛像玻璃钢雕塑定制承德玻璃钢雕塑定制玻璃钢艺术雕塑供应商玻璃钢雕塑的手糊制作步骤玻璃钢雕塑鉴别安徽水果玻璃钢雕塑销售厂家遵义玻璃钢雕塑制作哪家好昆山玻璃钢雕塑沈阳承接玻璃钢座椅雕塑玻璃钢雕塑鲨鱼临沂广场玻璃钢雕塑价格浙江仿铜玻璃钢雕塑销售电话福建玻璃钢花盆花器井冈山玻璃钢胡萝卜雕塑厂家在哪韶关人物玻璃钢卡通雕塑河源玻璃钢雕塑工艺动漫人物玻璃钢雕塑供应商河南卡通玻璃钢雕塑工厂安徽学校玻璃钢抽象艺术雕塑摆件定西玻璃钢植物雕塑价格西安仿铜玻璃钢雕塑定做铸铜玻璃钢彩绘雕塑制造玻璃钢米老鼠雕塑香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化