C++的explicit关键字修饰构造函数(或类型转换函数,C++11),表明该构造函数是explicit的,不能用作隐式的类型转换和拷贝初始化。
下面的代码中,类的构造函数没有explicit关键字修饰:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class A { public: A(string s) : name_(s) { } string getName() { return name_; } private: string name_; }
void useA(A a) { return a.getName(); }
|
所以,隐式的类型转换和拷贝初始化是合法的:
1 2 3 4 5 6
| string name = "Lucy";
cout << useA(name) << endl;
A a1(name); A a2 = name;
|
顺带说明一下,编译器只允许一次类型转换,执行了两次隐式类型转换的用法是错误的,后面给出了正确的用法:
1 2 3 4 5 6 7
| cout << useA("Lucy");
cout << useA(string("Lucy"));
cout << useA(A("Lucy"));
|
下面是加了explicit关键字修饰的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class B { public: B(string s) : name_(s) { } string getName() { return name_; } private: string name_; }
void useB(B b) { return b.getName(); }
|
构造函数为explicit,所以隐式的类型转换和拷贝初始化是不合法的。尽管编译器不会将explicit的构造函数用于隐式转换过程,但我们可以用它来显式地强制进行转换:
1 2 3 4 5 6 7 8 9 10
| string name = "Lucy";
cout << useB(name); cout << useB(B(name)); cout << useB(static_cast<B>(name));
B b1(name); B b2 = name; B b3 = B(name); B b4 = static_cast<B>(name);
|
应尽可能将构造函数声明为explicit,避免隐式的类型转换,可以减少出错。