可能是我的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的作用就是禁止構造函數隱式轉換。