一、explicit的作用
在C++中,explicit關鍵字可以在構造函數聲明前加上,防止編譯器進行自動類型轉換,強制要求調用者必須強制類型轉換才能調用該函數,避免了將一個參數類型轉換成其他類型的疏忽錯誤。
例如,有一個只有一個int參數的類的構造函數,如果我們不加explicit關鍵字,則可以直接將int隱式轉換成該類對象,如下所示:
class Test { public: Test(int num) { this->num = num; } private: int num; }; int main() { Test obj = 10; // 可以直接將10賦值給obj return 0; }
這樣做存在隱式類型轉換的風險,可能會導致不可預料的結果。為了避免這種情況,我們需要在構造函數聲明前加上explicit關鍵字:
class Test { public: explicit Test(int num) { this->num = num; } private: int num; }; int main() { Test obj(10); // 必須顯式地將10轉換成Test對象 return 0; }
二、explicit在類型轉換中的應用
explicit關鍵字也可用於定義轉換函數,將其標記為不允許隱式轉換。與構造函數不同,任何用於轉換目標類型的單參數構造函數都可以用作隱式轉換,即使它不帶explicit關鍵字。而對於轉換函數,explicit關鍵字對重載運算符類型轉換(比如+, ==)也是有效的。
例如:
class Test { public: int num; explicit Test(int num) { this->num = num; } operator int() { return num; } }; int main() { Test obj(10); int num1 = obj.num; int num2 = obj; return 0; }
在該示例中,我們定義了一個將Test類型轉換成int類型的轉換函數 operator int() 。由於沒有帶explicit關鍵字,因此可以進行隱式轉換,即可以直接將Test類型的對象賦值給int類型的變量。但是,如果我們在operator int()的前面加上explicit關鍵字,則只能顯式地將Test對象轉換成int類型:
class Test { public: int num; explicit Test(int num) { this->num = num; } explicit operator int() { return num; } }; int main() { Test obj(10); int num1 = obj.num; int num2 = obj; // 編譯錯誤:無法從Test轉換到int int num3 = static_cast(obj); return 0; }
三、explicit和默認參數的結合
如果不加explicit關鍵字,會導致默認參數的失效。例如:
class Test { public: explicit Test(int num1, int num2 = 0) { this->num1 = num1; this->num2 = num2; } private: int num1; int num2; }; int main() { Test obj1(10); // 編譯錯誤,無法匹配到參數 Test obj2(10, 20); // 正確 return 0; }
由於加了explicit關鍵字,導致默認參數無法正常使用。因此,要想使用默認參數必須添加默認參數的構造函數:
class Test { public: Test(int num1) { this->num1 = num1; this->num2 = 0; } Test(int num1, int num2) { this->num1 = num1; this->num2 = num2; } private: int num1; int num2; }; int main() { Test obj1(10); // 正確 Test obj2(10, 20); // 正確 return 0; }
四、explicit和模板結合
explicit關鍵字也可以用於模板中,來控制在模板實例化時,是否進行隱式類型轉換:
template class Test { public: explicit Test(T num) { this->num = num; } private: T num; }; int main() { Test obj1(10); Test obj2(10.5); Test obj3 = 10; // 編譯錯誤:無法從int轉換到Test Test obj4 = 10.5; // 編譯錯誤:無法從double轉換到Test return 0; }
如上所示,由於在模板中加了explicit關鍵字,所以無法進行隱式類型轉換,必須顯式地進行類型轉換。如果我們不加explicit關鍵字,則可以直接進行隱式類型轉換。
五、總結
在C++中,explicit關鍵字的主要作用是防止編譯器進行自動類型轉換,避免了將一個參數類型轉換成其他類型的疏忽錯誤。它可以在構造函數和轉換函數中使用,配合重載運算符類型轉換也是有效的。但是,explicit關鍵字有時會影響到默認參數的使用,也有可能造成代碼冗長,需要根據實際情況靈活應用。
原創文章,作者:BUZGG,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/373170.html