首先看下以下代碼
#include <iostream>
using namespace std;
class A
{
public:
A(int v): value(v) { cout << "構造" << endl;}
int value;
};
void f(A a)
{
cout << "f()" << endl;
}
int main()
{
f(1);
return 0;
}
以上代碼可以編譯通過之所以能夠調用函數f成功是因爲在調用函數之前,編譯器將整數1隱式地轉化爲對象A
如果我們在該構造函數之前加上 explicit 關鍵字,那麼,再次調用就失敗了,從 explicit字面意思就可以知道,explicit是
明確的,清楚的;直言的;詳述的;不隱瞞的意思,也就是阻止隱式轉換,所以,以下代碼編譯出錯
#include <iostream>
using namespace std;
class A
{
public:
explicit A(int v): value(v) { cout << "構造" << endl;}
int value;
};
void f(A a)
{
cout << "f()" << endl;
}
int main()
{
f(1);
return 0;
}
explicit的本質就是使得該函數顯示調用,不能隱式轉換,如果將以上的代碼中的f(1)改成f(A(1)),則編譯通過
考慮下面兩個語句
A a;
A b1(a);
A b2 = a;
顯然熟悉C++的同學都知道2,3兩句其實都是調用了A的拷貝構造函數,下面這段代碼可以檢驗一下
#include <iostream>
using namespace std;
class A
{
public:
A(){}
A(const A& a){cout << "拷貝構造" << endl;}
};
int main()
{
A a;
A b1(a);
A b2 = a;
return 0;
}
但是2,3兩句還是有細微的差別的,即 A b1(a);是顯示調用拷貝構造函數,而 A b2 = a;是隱式調用拷貝構造函數,所以,我們如果在拷貝構造函數前面加入explicit,就阻止了拷貝構造函數的隱式調用,進而使得 A b2 = a;編譯出錯
#include <iostream>
using namespace std;
class A
{
public:
A(){}
explicit A(const A& a){cout << "拷貝構造" << endl;}
};
int main()
{
A a;
A b1(a);
A b2 = a;
return 0;
}
最後:如果你能瞭解下面這段代碼爲什麼出錯,你就可以算得上懂得explicit的意義了
#include <iostream>
using namespace std;
class A
{
public:
A(){}
explicit A(const A& a){cout << "拷貝構造" << endl;}
};
void f(A a)
{
}
int main()
{
A a;
f(a);
return 0;
}
最後的組後,再偷偷地告訴你一個好消息:explicit只能用在構造函數哦^^