Welcome

首页 / 软件开发 / C++ / 关键字explicit的用法

关键字explicit的用法2011-04-06可能是我的C++基础不好,记不得explicit是干嘛用的了,所以网上搜了下,想想还是写下来,以免再忘,先来个例子,说明一下问题:

test.cc:
class A
{
public:
A(int a) : data(a){}
int data;
};
class B
{
public:
explicit B(int b) : data(b){}//就是这个了
int data;
};
void func_a()
{
A a = 0;
a = 1;
}
void func_b()
{
B b = 0;
b = 1;
}
int main()
{
func_a();
func_b();
return 0;
}

& gcc test.cc -o test

编译信息:

test.cc: In function "void func_b()"
test.cc:29 error: no match 为 "operator="在 "b = 1"中
test.cc:14 B& B::operator=(const B&)

也就是说在func_b()中的语句 "b = 1;" 错误,没有在类B中找到"="的操作符重载。而与类B相同定义的类A中没有错误的原因就是因为类A的constructor没有声明为explicit,这就是所谓的隐式转换。

分析一下:

A a = 0;

其实正确的写法应该是A a(0);

编译器认为这种写法是不规范的,但通过搜索,发现A中有一个没有被explicit修饰过的A(int a),可以进行隐式转换,这样的一句话变成了

A tmp(0);
A a = tmp;//调用默认的copy constructor

一句变两句了,所以提高效率要记得用A a(0); 而不要用A a = 0;

那么语句 a = 1; 也就相当于:

A tmp(1);
a = tmp;

这种转换不仅发生于assignment,也可能发生于函数调用,例如

func(A a){}
int main()
{
func(1);
}

类似地,这个调用func(1);也被隐式转换成了

A tmp(1);
fun(tmp);

class B的constructor被声明为了expcilit,编译器就认为你不想让编译器为你做隐式转换,所以func_b就error了。

so, explicit的作用就是禁止构造函数隐式转换。