【C++永不过时的语言】C++关键字explicit
发布日期:2021-06-29 14:30:09 浏览次数:4 分类:技术文章

本文共 1390 字,大约阅读时间需要 4 分钟。

文章目录

explicit是C++的一个关键字,你可能很少用到它,但稍微留心一下就会发现C++标准库中explicit出现的频率还是挺高的。了解explicit关键字的功能及其使用对于我们阅读使用库是很有帮助的,而且在编写自己的代码时也可以尝试使用。

那么这个关键字到底有什么作用呢?带着问题我们好好的认识下这个"家伙",要明白explicit关键字的用途,首先需要了解隐式类型转换。

1.什么是隐式转换构造函数

在《C++ Primer》这本经典教程中提到:可以用单个实参来调用的构造函数定义从形参类型到该类类型的一个隐式转换。这句话看起来比较绕口挺不好理解的。我们还是结合实例来理解。

在这里插入图片描述

上面的例子中,Compex(double r, double i = 0)这个构造函数就是前面所说的可以用单个实参来调用的构造函数 ,因为它的第二个参数是默认参数。像这样的函数也称为转换构造函数。

那什么又是从形参类型到该类类型的一个隐式转换了? 在上例中,1,2,3处(截图中已经标明)就发生了所谓的从形参类型到该类类型的一个隐式转换 。

我们以第3处的函数调用print(10)为例,由于print 函数定义时是接收一个Complex类型的参数,现在调用时传了个10,由于转换构造函数的存在,可以将10隐式转换 为一个临时Complex 对象传递过去。

看到没,通过10得到了类Complex对象,这就是以转换构造函数形参类型(此处是double类型—10可以隐式转换为double类型)到该类类型(这个临时对象)的隐式转换

到这里,我相信大家应该明白了什么是隐式转换构造函数了吧。

2.隐式转换的隐患

隐式类型转换表面上看给我们带来了很大的方便,但是实际上很多时候却会给我们代码埋下很深的隐患,看看下面的代码。

在这里插入图片描述

在这里插入图片描述

从上面可以看出,第14行原本我们是想写 Mystring s1 = “a”,通过构造函数2将s1初始化为字符串"a"的,结果不小心将双引号" "写成了单引号’ ',由于转换构造函数1(功能是创建size大小的字符串)的存在,它会用’a’构造出一个临时的Mystring 对象(含97(a的ascii码)字节的字符串)来初始化s1。结果s1被初始化为了含97字节的字符串。

上面那种情况并不是我们希望的,程序运行的时候,凡是用到s1的地方都可能出现逻辑错误,而这种错误又是很难定位的。

那么有没有一种办法可以预防这种情况的发生?现在是该我们讲述explicit 关键字的时候了。

3.explicit 关键字用法

好了,经过前面那么长铺叠,现在终于轮到我们的主角explicit 登场了,前面说了隐式转换常常会带来程序逻辑的错误,而且这种错误一旦发生是很难察觉的,应当尽量避免。

那么怎么避免这种隐式转换 ,这就是关键字explicit的作用了,在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种转换。

在这里插入图片描述

在这里插入图片描述

可以看出,当构造函数前加了explicit关键字后,原本代码中发生隐式转换的地方现在在编译的时候不能通过,这样,也就防止了我们程序中可能出现的问题,记住,编译器是我们最好的朋友,我们尽可能的将代码中的隐患错误暴露给编译器,让它提醒我们以便及时去纠正我们的错误。

需要注意的是,explicit 只能出现在构造函数的声明中。

学如逆水行舟,不进则退

转载地址:https://chocolate.blog.csdn.net/article/details/104187624 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【C++永不过时的语言】=运算符重载应注意点
下一篇:【C++永不过时的语言】关于C++中的类型转换

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月15日 04时01分17秒