开场白
本来想总结一下explicit关键字的用法,结果看了官方文档发现能给拷贝构造加explicit,我就去试了试
试了之后,又发现了两个大坑:隐式类型转换和编译器优化,本来我以为我很久以前就理解了这俩概念,但是一系列实验结果表明这并不是那么简单
这两个坑折磨得我欲仙欲死
首先贴一下我们一直说的编译器优化是什么,官网的定义
编译器优化学名叫:拷贝省略
Copy elision
Omits copy and move (since C++11) constructors, resulting in zero-copy pass-by-value semantics.
The compilers are required to omit the copy and move construction of class objects
注意,本博客基于VS2019进行实验
前言
相比于C语言的32个关键字,C++98开始陆续增加了很多C++关键字使得C++的新特性越来越多
我们今天来谈谈C++98增加的explicit
关键字
根据以前的理解,在单参数构造函数之前加explicit会导致我们不能使用隐式类型转换的方式去实例化对象
那么我们来看一看官方文档是怎么说的
目录
explicit的功能
根据官方文档 https://en.cppreference.com/w/cpp/language/explicit
explicit的作用是:
Specifies that a constructor or conversion function (since C++11) or deduction guide (since C++17) is explicit, that is, it cannot be used for implicit conversions and copy-initialization.
A constructor with a single non-default parameter (until C++11) that is declared without the function specifier explicit is called a converting constructor.
意思是用explicit修饰了构造函数后,就不支持隐式的
转换
和拷贝初始化
不支持隐式类型转换我可以理解,那么不支持拷贝构造是什么意思呢?
(事后来看,我英文没看懂,而且没有明白隐式类型转换的真正含义。)
这句话的真正意思是:explicit关键字能让构造函数不可被隐式地调用, implicit conversions
指的是隐式地用单个参数构造一个对象,copy-initialization
指的是隐式地调用拷贝构造,用一个对象构造另一个对象
也就是说这两种构造对象的隐式调用都能被explicit禁!
但事情远没这么简单
代码研究
我们简单模拟了一个my_string的类,给了`单参构造和拷贝构造`class my_string {
public:
my_string(const char* str) {
size_t len = strlen(str);
_str = new char[len + 1];
memcpy(_str, str, len + 1);
_size = _capacity = len;
}
my_string(const my_string& str) {
size_t len = strlen(str._str);
_str = new char[len + 1];
memcpy(_str, str._str, len + 1);
_size = _capacity = len;
private<