C++中explicit的作用

最近到读Effective C++,里面提到了explicit关键字,它是用来阻止构造函数被用来执行隐式类型转换。虽然平时中很少使用到这个关键字,但是不难发现C++标准库中的相关类声明中explicit出现的频率是很高的,既然C++语言提供这种特性,我想在有些时候这种特性将会非常有用,下面说说我对explicit的认识。

C++中explicit关键字,实际上只对构造函数起作用。
可以用实例来表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;
class Example
{
public:
Example(int n)
{
num = n;
}
void Print()
{
cout << num << endl;
}
private:
int num;
};
int _tmain(int argc, _TCHAR* argv[])
{
Example example = 10;
example.Print();
example = 'a';
example.Print();
system("pause");
return 0;
}

以上代码输出的结果分别为10 97
显然,我们本意是不需要‘a’来初始化的
因为这样可能会造成不必要的错误
由于是隐式转换,编译器不会报错,所以但出现问题是会很难查找到错误

这时候explicit就体现出它的作用了,把上面的代码修改一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;
class Example
{
public:
explicit Example(int n)
{
num = n;
}
void Print()
{
cout << num << endl;
}
private:
int num;
};
int _tmain(int argc, _TCHAR* argv[])
{
//Example example = ‘a'; 这样的隐式转换会报错
Example example(10); //只能显示调用
example.Print();
system("pause");
return 0;
}

在实际代码中的东西可不像这种故意造出的例子。
发生隐式转换,除非有心利用,隐式转换常常带来程序逻辑的错误,而且这种错误一旦发生是很难察觉的。
原则上应该在所有的构造函数前加explicit关键字,当你有心利用隐式转换的时候再去解除explicit,这样可以大大减少错误的发生。