C++的explicit關鍵字

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

相關文章
相關標籤/搜索