explicit用来防止由构造函数定义的隐式转换。
隐式转换:可以由单个实参来调用的构造函数定义了一个从形参类型到该类类型的隐式转换。
例如:
#include<iostream> using namespace std; class Test { private: int a; int b; public: Test(int x){ a=x; } int get(){ return a; } }; void print(Test t){ cout<<t.get()<<endl; } int main(){ print(100); return 0; }Test类的构造函数就定义了一个从int类型到Test类型的隐式转换。
编译器在试图编译某一条语句时,如果某一函数的参数类型不匹配,编译器就会尝试进行隐式转换,如果隐式转换后能正确编译,编译器就会继续执行编译过程,否则报错。
例如在上述代码中的print(100)语句中,100是int类型的数据,而print函数的参数要求是Test类型的,类型不匹配,编译器就会利用Test的构造函数进行隐式转换,将100转换为一个Test类型的实例,而后继续编译。
上述代码最终能够正确编译,最终执行结构为:
而explicit关键字是阻止单参数构造函数的这种隐式转换机制。
如果在上述的代码中的Test构造函数前面加上explicit修饰的话,编译就会出错,如下:
由此可见,被声明为explicit的构造函数禁止编译器执行非预期的类型转换。