以前在Qt中就经常碰到过,最近看回点书,总结一下。
主要作用是防止隐式转换构造函数。
例如:
class A
{
int a;
public:
explicit A(int i):a(i){}
};
int main()
{
A a(1),b(2);
a = b;
a = 2; //错误,不能隐式转换
return 0;
}
当执行到a=2时候,
编译器认为这样是不合规范的,因为A = A才是正常行为。但是她并不放弃, 通过搜索, 发现A可以根据一个int构造, 同时这个A(int i)没有用explicit修饰过。
那么A a = 0; 这样的一句话随即转变成:
A tmp(0);
A a = tmp;
需要说明的是, A a = tmp是调用的copy ctor, 虽然class A中并没有, 但是通常不写copy ctor的话,编译器都会生成一个memberwise assignment操作性质的ctor, 底层实现通常会以memcpy进行,这样会容易导致浅拷贝。
因此,对于explicit, 当修饰explicit A(int i) : m_i(i){}, 那么即告诉compiler不要在私底下做那么多的转换动作。而且自动生成如A tmp(0)这样的东西是我们不想要的, 因为某些情况下自动转换这种行为是错误的.
-------------
明确的构造函数(Explicit Constructors)
对单参数构造函数使用C++关键字explicit。
定义:通常,只有一个参数的构造函数可被用于转换(conversion,译者注:主要指隐式转换,下文可见),例如,定义了Foo::Foo(string name),当向需要传入一个Foo对象的函数传入一个字符串时,构造函数Foo::Foo(string name)被调用并将该字符串转换为一个Foo临时对象传给调用函数。看上去很方便,但如果你并不希望如此通过转换生成一个新对象的话,麻烦也随之而来。为避免构造函数被调用造成隐式转换,可以将其声明为explicit。
优点:避免不合时宜的变换。
缺点:无。
结论: 所有单参数构造函数必须是明确的。在类定义中,将关键字explicit加到单参数构造函数前:explicit Foo(string name); 例外:在少数情况下,拷贝构造函数可以不声明为explicit;特意作为其他类的透明包装器的类。类似例外情况应在注释中明确说明。
via :http://blog.youkuaiyun.com/fornormandy/article/details/79512