在c++种explicit关键字只能用来修饰构造函数。使用explicit可以禁止编译器自动调用拷贝初始化,还可以禁止编译器对拷贝函数的参数进行隐式转换。
什么是拷贝初始化?
举个例子:
现在我们不使用explicit关键字看看会发生什么?我们发现下面这个代码明明我们给函数f()传递的参数是一个整数,但是编译器却自动调用了类A的构造函数,这种就叫做拷贝初始化。这是超出预期的。如果你不希望这样那么请在构造函数前面加上explicit关键词禁止编译器这种自动调用拷贝初始化的行为,即explicit A(int x){}。
#include <iostream>
using namespace std;
class A{
public:
A(int x){
cout<<"我被用了"<<endl;
}
};
void f(A a)
{
}
int main( ){
f(1);// 被隐式转换为f(A(1)) ,本来是1却被自动调用了A(1)这就是拷贝初始化
//输出:"我被调用了"
return 0;
}
什么是编译器会对构造函数的参数进行隐式转换?
假设你想写个类把整数或者字符数组变成字符串。下面代码如果不使用explicit关键字你会发现下面这个程序会有bug。
#include <iostream>
using namespace std;
#include<algorithm>
class Str{
public:
Str(int x){
cout<<"我是想把整数变字符串"<<endl;
}
Str(const char* a)
{
cout<<"我是想把字符数组变字符串"<<endl;
}
};
int main( ){
Str s='c';
// 输出:"我是想把整数变字符串"
// 它把'c'的ASCII码传进去了,如果这样变成字符串那就得到一个数字,
// 而我们期待的是把'c'变成字符串。
return 0;
}