C++中的關鍵字explicit主要是用來修飾類的構造函數,被修飾的構造函數的類,不能發生相應的隱式類型轉換,只能以顯示的方式進行類型轉換。類構造函數默認情況下聲明為隱式的即implicit。
隱式轉換即是可以由單個實參來調用的構造函數定義了一個從形參類型到該類類型的隱式轉換。編譯器在試圖編譯某一條語句時,如果某一函數的參數類型不匹配,編譯器就會嘗試進行隱式轉換,如果隱式轉換后能正確編譯,編譯器就會繼續執行編譯過程,否則報錯。
explicit關鍵字只能用於類內部的構造函數聲明上,而不能用在類外部的函數定義(函數實現)上,它的作用是不能進行隱式轉換;explicit關鍵字作用於單個參數的構造函數,如果構造函數有多個參數,但是從第二個參數開始,如果各參數均有默認賦值,也可以應用explicit關鍵字。
當構造函數只有一個參數時,會進行自動隱式轉換,當構造函數參數個數超過或等於兩個時自動取消隱式轉換,當只有一個必須輸入的參數,其余的為有默認值的參數時使用explicit也起作用。
一般只將有單個參數的構造函數聲明為explicit,而拷貝構造函數不要聲明為explicit。
explicit關鍵字只能對用戶自己定義的對象起作用,不對默認構造函數起作用。此關鍵只能夠修飾構造函數。無參數的構造函數和多參數的構造函數總是顯示調用,這種情況在構造函數前加explicit無意義。
當不希望進行自動類型轉換時用explicit,標准庫的許多構造函數都是explicit的。
以下是參考網上的一個測試代碼:
explicit.hpp:
-
-
-
-
// reference Bjarne Stroustrup sample
-
class String{
-
public:
-
explicit String(int n) {};
-
String( const char *p) {};
-
};
-
-
void test_explicit();
-
-
explicit.cpp:
-
-
-
static void test1()
-
{
-
String s1 = 'a'; // 錯誤:不能做隱式char->String轉換
-
String s2(10); // 可以:調用explicit String(int n);
-
String s3 = String( 10); // 可以:調用explicit String(int n);再調用默認的復制構造函數
-
String s4 = "Brian"; // 可以:隱式轉換調用String(const char *p);再調用默認的復制構造函數
-
String s5("Fawlty"); // 可以:正常調用String(const char *p);
-
}
-
-
static void f(String)
-
{
-
-
}
-
-
static String g()
-
{
-
f( 10); // 錯誤:不能做隱式int->String轉換
-
f( "Arthur"); // 可以:隱式轉換,等價於f(String("Arthur"));
-
return 10; // 同上
-
}
-
-
void test_explicit()
-
{
-
test1();
-
g();
-
}
執行情況如下:
