【C++】explicit关键字详解(explicit关键字是什么? 为什么需要explicit关键字? 如何使用explicit 关键字) | 您所在的位置:网站首页 › 编程的关键是什么 › 【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,这就是编译器会做的一件事💬小蛋:不是说构造函数有初始化列表吗?拷贝构造怎么去初始化呢? //拷贝构造 Date(const Date& d) :_year(d._year) ,_month(d._month) ,_day(d._day) {} 同学,别忘了【拷贝构造】也是属于构造函数的一种哦,也是会有初始化列表的刚才说到了中间会产生一个临时对象,而且会调用构造 + 拷贝构造,那此时我们在Date类中写一个拷贝构造函数,调试再去看看会不会去进行调用 很明显没有,我在进入Date类后一直在按F11,但是却进不到拷贝构造中,这是为什么呢?💬小蛋:但您是怎么知道中间赋值这一块产生了临时对象呢?如果不清楚编译器的优化机制这一块肯定就会认为这里只有一个构造 这点确实是,若是我现在不是直接赋值了,而是去做一个引用,此时会发生什么呢? Date& d3 = 2024; 可以看到,报出了一个错误,原因就在于d3是一个Date类型,2024则是一个内置类型的数据但若是你不想让这种隐式类型转换发生怎么办呢?此时就可以使用到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 };那要如何去防止这样的隐式类型转换发生呢,还是可以使用到explicit关键字吗? //多参构造函数 explicit Date(int year, int month ,int day = 31) :_year(year) ,_month(month) ,_day(day) {} 可以看到,加上explicit关键字做修饰,同样可以起到【禁止类型转换】的作用所以对于可读性不是很好的代码,可以使用explicit修饰构造函数,将会禁止构造函数的隐式转换 ✨ 怎么使用explicit关键字?explicit关键字在C++中只能用于修饰类的构造函数,它用来修饰只有一个参数的类构造函数,以表明该构造函数是显式的,而非隐式的。 只要在构造函数名前加上explicit就能禁止类对象之间的隐式转换、禁止隐式调用拷贝构造函数。 四、总结以下就是我对C++ explicit关键字的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++ 的理解,请持续关注我哦!!! |
CopyRight 2018-2019 实验室设备网 版权所有 |