【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.mzph.cn/bicheng/1809.shtml

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

相关文章

CentOS 7离线升级OpenSSH至9.1p1操作过程及遇上的问题

在文章顶部下载适用于CentOS7的OpenSSH 9.1p1 rpm包,包含了服务器和客户端。 默认全部以root用户权限执行命令。 简单版 懒得看的话,复制以下4行命令执行即可。 tar -zxvf centos7-openssh-9.1p1.tar.gz rpm -Uvh openssh-9.1p1-1.tl2.x86_64.rpm op…

第十四届蓝桥杯 子串简写 | 树状数组解法

Problem: 第十四届蓝桥杯 子串简写 程序猿圈子里正在流行一种很新的简写方法: 对于一个字符串,只保留首尾字符,将首尾字符之间的所有字符用这部分的长度代替。 例如 internationalization 简写成 i18n,Kubernetes 简写成 K8s&am…

npx\pnpm 镜像过期解决方法

. // 1. 清空缓存 npm cache clean --force // 2. 关闭SSL验证 npm config set strict-ssl false // 3. 安装 到这里就可以正常使用npm命令安装需要的工具了。如( npm install -g cnpm )

虚拟机中使用LNMP模拟跨域并结合前端代码解决CORS跨域的简单示例

目录 一、首先,下载lnmp_soft.tar.gz压缩包 二、解压lnmp_soft.tar.gz和下载相关的依赖,插件 三、修改/usr/local/nginx/conf/nginx.conf配置文件 四、/usr/local/nginx/sbin/nginx命令启动nginx 五、在/usr/local/nginx/html目录下新建80.html&…

D. Nene and the Mex Operator - dfs + 位运算枚举

题面 分析 将一段区间[l, r]变成最大,可以遵循以下规则,先对第一个数进行操作,如果他是0, 那么会变成1,所以不进行操作,如果不是0,就要进行操作,让它变成0,只有这样才能…

书生·浦语大模型实战营之微调 Llama 3 实践与教程 (XTuner 版)

书生浦语大模型实战营之微调 Llama 3 实践与教程 (XTuner 版) Llama 3 近期重磅发布,发布了 8B 和 70B 参数量的模型,XTuner 团队对 Llama 3 微调进行了光速支持!!!开源同时社区中涌现了 Llama3-XTuner-CN 手把手教大家使用 XTuner 微调 Llama 3 模型。 XTuner:http:/…

图深度学习——2.图的理论知识

1.图 1.1 图的定义 图是由节点&#xff08;顶点&#xff09;和边构成的数学结构。图用于表示对象之间的关系&#xff0c;其中节点表示对象&#xff0c;边表示对象之间的关系。 一个图&#xff0c;记为 G <V, E> &#xff0c;它包括以下两个要素&#xff1a; 1.节点&am…

[C++ 多线程并发] std::async

c11中增加了线程&#xff0c;使得我们可以非常方便的创建线程&#xff0c;它的基本用法是这样的&#xff1a; void f(int n); std::thread t(f, n 1); t.join();但是线程毕竟是属于比较低层次的东西&#xff0c;有时候使用有些不便&#xff0c;比如我希望获取线程函数的返回结…

第22天:安全开发-PHP应用留言板功能超全局变量数据库操作第三方插件引用

第二十二天 一、PHP留言板前后端功能实现 开发环境&#xff1a; DW PHPStorm PhpStudy Navicat Premium DW : HTML&JS&CSS开发 PHPStorm : 专业PHP开发IDE PhpStudy &#xff1a;Apache MYSQL环境 Navicat Premium: 全能数据库管理工具 二、数据库创建&架…

机器学习(三)之监督学习2

前言&#xff1a; 本专栏一直在更新机器学习的内容&#xff0c;欢迎点赞收藏哦&#xff01; 笔者水平有限&#xff0c;文中掺杂着自己的理解和感悟&#xff0c;如果有错误之处还请指出&#xff0c;可以在评论区一起探讨&#xff01; 1.支持向量机&#xff08;Support Vector Ma…

iTwin Capture Modeler-23中文版下载地址及安装教程

文章目录 一、iTwin Capture Modeler23中文版安装教程二、iTwin Capture Modeler23中文版下载地址一、iTwin Capture Modeler23中文版安装教程 1. 解压安装包。订阅专栏(可获取专栏内所有文章阅读权限与软件安装包)后,从文末获取安装包解压,如下所示: 2. 右击安装包,选择以…

【Web】HNCTF 2022 题解(全)

目录 Week1 Interesting_include 2048 easy_html What is Web Interesting_http easy_upload Week2 ez_SSTI easy_include ez_ssrf Canyource easy_unser easy_sql ohmywordpress Week3 ssssti Fun_php ez_phar QAQ_1inclu4e logjjjjlogjjjj …

图像哈希:Global+Local

文章信息 作者&#xff1a;梁小平&#xff0c;唐振军期刊&#xff1a;ACM Trans. Multimedia Comput. Commun. Appl&#xff08;三区&#xff09;题目&#xff1a;Robust Hashing via Global and Local Invariant Features for Image Copy Detection 目的、实验步骤及结论 目…

oai调试

1、修改docker-compose脚本 entrypoint: ["/bin/sh", "-c", "while true; do echo Hello World; sleep 1; done"] oai-upf:container_name: "oai-upf"image: oaisoftwarealliance/oai-upf:v2.0.1### 修改entrypointentrypoint: [&qu…

设计模式(023)行为型之中介者模式

中介者模式是一种行为型设计模式&#xff0c;用于减少对象之间的直接通信&#xff0c;而是通过一个中介对象来进行间接通信。这种模式有助于减少对象之间的耦合&#xff0c;使得系统更易于维护和扩展。 在中介者模式中&#xff0c;主要有以下几个角色&#xff1a;① 中介者&…

内网隧道技术总结

隧道技术解决的是网络通信问题&#xff0c;因为在内网环境下&#xff0c;我们不同的内网主机管理员会进行不同的网络配置&#xff0c;我们就需要使用不同的方式去控制我们的内网主机。隧道技术是一个后渗透的过程&#xff0c;是可以是我们已经取得了一定的权限&#xff0c;在这…

返回稀疏矩阵csr_matrix的对角线元素

diagonal matrix numpy python scipy Return diagonal elements of scipy sparse matrix https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.lil_matrix.html 给定scipy.sparse.csr.csr_matrix&#xff0c;有没有一种快速的方法可以返回对角线上的元素&…

MySQL运维故障解决方案:实战案例与深度解析

一、引言 MySQL数据库在企业应用中扮演着举足轻重的角色&#xff0c;但在运维过程中时常会遭遇各类故障。本文不仅梳理了常见的MySQL运维故障&#xff0c;还通过实战案例&#xff0c;展示了如何解决这些故障&#xff0c;确保数据库稳定运行。 二、常见故障及解决方案 1. 连接问…

NLP任务全览:涵盖各类NLP自然语言处理任务及其面临的挑战

自然语言处理(Natural Language Processing, 简称NLP&#xff09;是计算机科学与语言学中关注于计算机与人类语言间转换的领域。NLP将非结构化文本数据转换为有意义的见解&#xff0c;促进人与机器之间的无缝通信&#xff0c;使计算机能够理解、解释和生成人类语言。人类等主要…

(四)openlayers加入矢量图层.json文件

openlayers加入矢量图层.json文件 &#xff08;1&#xff09;接上一章节&#xff0c;添加矢量图层.json文件。首先下载.json矢量图层文件。链接&#xff1a;JSON矢量图层文件 &#xff08;2&#xff09;导入相关的依赖&#xff0c;提前把你下载好的矢量文件放入assets文件夹下…