explicit 可用来阻止类构造函数的隐式转换
如:
class Test {
public:
Test(int num) : num_(num) {
std::cout << "num struct " << this << std::endl;
}
Test(const Test &test) {
num_ = test.num_;
std::cout << "copy struct " << this << std::endl;
}
private:
int num_;
};
int main() {
Test test = 10;
Test test1 = test;
return 0;
}
这里隐藏了两种隐式转换:
Test test = 10;
Test test(10); 相当于调用Test(int num) 构造函数
Test test1 = test;
Test test1(test);相当于调用Test(const Test &test)拷贝构造函数
这些操作都是隐式转化的
而如果构造函数需要明确显示调用,而不运行隐式调用可能隐含的bug。
可以在这些构造函数前面使用explicit关键字,这样在编译的时候,凡遇到这种需要隐式替换的地方,编译器便会报错。
这样能保证成功编译后的程序是按照程序员显示调用所想的方式的进行。
一个例子:
std::lock_guard的锁的构造函数便是explicit关键字的,这是因为我们想要进行锁定,是我们明确想要进行的,
而不应该是隐式转换导致我们可能没有想到的情况,而导致锁定
template<typename _Mutex> class lock_guard
{ public:
typedef _Mutex mutex_type;
explicit lock_guard(mutex_type& __m) : _M_device(__m)
{ _M_device.lock(); }
};