服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++ 之explicit关键字

C++ 之explicit关键字

2023-04-10 17:17烽起黎明 C/C++

今天我们来谈谈C++中的explicit关键字,这篇文章详细介绍了C语言的关键字explicit关键字,本文有详细的代码实例,感兴趣的同学可以借鉴参考

构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用

一、单参构造函数

  • 还是老朋友,我们通过下面这个日期类进行讲解
?
1
2
3
4
5
6
7
8
9
10
11
12
class Date
{
public:
    Date(int year)
        :_year(year)
    {}
 
private:
    int _year;
    int _month = 3;
    int _day = 31;
};

对于下面的d1很清楚一定是调用了有参构造进行初始化,不过对于d2来说,也是一种构造方式

?
1
2
3
4
5
6
7
int main()
{
    Date d1(2022);
    Date d2 = 2023;
    
    return 0;
}

依旧通过调试来看就会非常清晰,这种写法也会去调用构造函数

C++ 之explicit关键字

在操作符章节,我有提到过【隐式类型转换】这个概念,像下面将一个int类型的数值赋值给到一个double类型的数据,此时就会产生一个隐式类型转换

?
1
2
int i = 1;
double d = i;
  • 对于类型转换而言,我在C++引用一文中也有提到过,这里并不是将值直接赋值给到左边的对象,而是在中间呢会产生一个临时变量,例如右边的这个i会先去构造一个临时变量,这个临时变量的类型是[double]。把它里面的值初始化为1,然后再通过这个临时对象进行拷贝构造给d,这就是编译器会做的一件事
  • 那对于这个d2其实也是一样,2023会先去构造一个临时对象,这个临时对象的类型是[Date]把它里面的year初始化为2023,然后再通过这个临时对象进行拷贝构造给到d2

C++ 之explicit关键字

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

?
1
2
3
4
5
6
//拷贝构造
Date(const Date& d)
    :_year(d._year)
    ,_month(d._month)
    ,_day(d._day)
{}

同学,别忘了【拷贝构造】也是属于构造函数的一种哦,也是会有初始化列表的

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

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

C++ 之explicit关键字

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

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

  • 这点确实是,若是我现在不是直接赋值了,而是去做一个引用,此时会发生什么呢?
?
1
Date& d3 = 2024;

可以看到,报出了一个错误,原因就在于d3是一个Date类型,2024则是一个内置类型的数据

C++ 之explicit关键字

  • 但若是我在前面加一个const做修饰后,就不会出现问题了,这是为什么呢?

C++ 之explicit关键字

其实这里的真正原因就在于产生的这个【临时变量】,它就是通过Date类的构造函数构造出来的,同类型之间可以做引用。还有一点就是临时变量具有常性,所以给到一个const类型修饰对象不会有问题

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

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

C++ 之explicit关键字

二、多参构造函数

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

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

C++ 之explicit关键字


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

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

?
1
Date d2 = { 2023, 3 };

C++ 之explicit关键字

  • 不仅如此,对于下面这种也同样适用,调用构造去产生一个临时对象
?
1
const Date& d3 = {<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E--> 2024, 4 };

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

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

C++ 之explicit关键字

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

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

以上就是C++ 之explicit关键字的详细内容,更多关于explicit关键字的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/Fire_Cloud_1/article/details/129968482

延伸 · 阅读

精彩推荐
  • C/C++C语言中自动隐式转换与类型强制转换实例分析

    C语言中自动隐式转换与类型强制转换实例分析

    这篇文章主要介绍了C语言中自动隐式转换与类型强制转换实例分析,需要的朋友可以参考下...

    C语言程序设计11442021-01-24
  • C/C++Mingw64编译wxWidgets 3.0.2常见错误分析

    Mingw64编译wxWidgets 3.0.2常见错误分析

    这篇文章主要介绍了Mingw64编译wxWidgets 3.0.2常见错误分析,需要的朋友可以参考下...

    C++教程网12312021-04-21
  • C/C++使用QGraphicsView实现气泡聊天窗口+排雷功能

    使用QGraphicsView实现气泡聊天窗口+排雷功能

    这篇文章主要介绍了使用QGraphicsView实现气泡聊天窗口+排雷,重点给大家介绍使用QWebEngineView控件内嵌html+CSS的实现方式,需要的朋友可以参考下...

    0小野人05982022-11-17
  • C/C++C++的指针,引用和STL详解

    C++的指针,引用和STL详解

    这篇文章主要为大家详细介绍了C++的指针,引用和STL,使用数据库,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    jiangchao988442022-09-29
  • C/C++C++中的类模板详解及示例

    C++中的类模板详解及示例

    我们在定义函数时,可以通过定义函数模板,来简化一些功能相同而数据类型不同的函数的定义和调用过程...

    C++教程网7142021-01-07
  • C/C++C++基于hook iat改变Messagebox实例

    C++基于hook iat改变Messagebox实例

    这篇文章主要介绍了C++基于hook iat改变Messagebox的方法,以实例形式展示了针对IAT(即导入地址表)以及hook的操作,有助于深入理解Windows程序设计原理,需要的...

    C++教程网11772021-02-07
  • C/C++C语言 动态分配数组案例详解

    C语言 动态分配数组案例详解

    这篇文章主要介绍了C语言 动态分配数组案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...

    吉大秦少游3922021-12-16
  • C/C++浅析ORB、SURF、SIFT特征点提取方法以及ICP匹配方法

    浅析ORB、SURF、SIFT特征点提取方法以及ICP匹配方法

    这篇文章主要为大家介绍了常用的特征点提取方法(ORB、SURF、SIFT)和ICP匹配方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...

    长沙有肥鱼11662022-07-28