引言
在 C++ 程序中很少有人去使用 explicit 关键字,不可否认,在平时的实践中确实很少能用得上。但稍微留心一下就会发现现有的 MFC 库或者 C++ 标准库中的相关类声明中 explicit 出现的频率是很高的。了解 explicit 关键字的功能及其使用对于我们阅读使用库是很有帮助的,而且在编写自己的代码时也可以尝试使用。既然 C++ 语言提供这种特性,我想在有些时候这种特性将会非常有用。
目的
通过将构造函数声明为 explicit(显式)的方式可以抑制隐式转换。也就是说,explicit 构造函数必须显式调用。
例子
引用 Bjarne Stroustrup 的例子:
class String{
explicit String(int n);
String(const char *p);
};
String s1 = 'a'; //错误:不能做隐式char->String转换
String s2(10); //可以:调用explicit String(int n);
String s3 = String(10); //可以:调用explicit String(int n);再调用默认的复制构造函数
String s4 = "Brian"; //可以:隐式转换调用String(const char *p);再调用默认的复制构造函数
String s5("Fawlty"); //可以:正常调用String(const char *p);
void f(String);
String g()
{
f(10); //错误:不能做隐式int->String转换
f("Arthur"); //可以:隐式转换,等价于f(String("Arthur"));
return 10; //同上
}
在实际代码中的东西可不像这种故意造出的例子。
发生隐式转换,除非有心利用,隐式转换常常带来程序逻辑的错误,而且这种错误一旦发生是很难察觉的。
原则上应该在所有的构造函数前加 explicit 关键字,当你有心利用隐式转换的时候再去解除 explicit,这样可以大大减少错误的发生。
class ClassName
{
explicit ClassName(int args);
virtual ~ClassName();
};