C++程序員對於explicit這個關鍵字其實不是很熟悉,至少我是如此;緣由在於其使用範圍不大,並且做用也沒有那麼大。
可是這不是說明咱們的程序中不須要這個關鍵字,按Google的C++編程規範和Effective C++的推薦看,咱們最好將只有一個參數的構造函數都加上這個關鍵字,這同時也是cppcheck的要求。c++
explicit意味着明確的,肯定的,這代表這個構造函數是沒法隱式轉換的,其反義詞正式implicit。沒有了隱式轉換,咱們則須要顯式使用某個類型的構造函數,如此,能夠規避不少不那麼能拿得出手的外部類的調用。程序員
指定構造函數或轉換函數(從c++ 11開始)是顯式的,也就是說,它不能用於隱式轉換和複製初始化編程
一個構造函數只有一個非默認參數(從c++ 11開始),沒有explicit聲明的,稱爲轉換構造函數。ide
咱們來看一個使用explicit 的代碼函數
class explicitConstruct { public: explicitConstruct(); explicitConstruct(int i){ std::cout << "we use interger parameter is "<<i <<"\n"; } explicitConstruct(int i,int j) { std::cout << "we use double interger parameter is "<<i<<" and "<<j<<"\n"; } }; class explicitConstructB { public: explicit explicitConstructB(int i){ std::cout << "we use explicit explicitConstructB interger parameter is "<<i <<"\n"; } explicit explicitConstructB(int i,int j){ std::cout << "we use explicit explicitConstructB double interger parameter is "<<i<<" and "<<j<<"\n"; } }; };
explicitConstruct和explicitConstructB類的惟一區別是explicitConstructB的構造函數加入了explicit。
如下是測試代碼測試
explicitConstruct i(3);//ok explicitConstruct j(3,4); //ok explicitConstructB ii(3);//ok explicitConstructB jj(3,4);//ok explicitConstruct k = 3;//ok explicitConstruct l = {3,4};//ok // explicitConstructB kk = 3; //error! copy-initialization does not consider explicitConstructB::explicitConstructB(int) // explicitConstructB ll = {3,4};///error! copy-initialization does not consider explicitConstructB::explicitConstructB(int,int) explicitConstructB kkk = explicitConstructB(3);//ok explicitConstructB lll = explicitConstructB(3,4);//ok
測試代碼很清楚的說明了explicit關鍵字發揮的做用,即讓類對象的構造過程沒法使用隱式轉換的方式調用拷貝初始化。這樣作的好處在於,咱們能夠嚴格控制構造器參數的類型,避免發生歧義。code