首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ explicit 關鍵字詳解:阻止隱式轉換的正確用法

     編輯:關於C++

explicit 修飾單一參數建構函數,禁止編譯器執行隱式型別轉換。若無 explicit,編譯器會自動將對應型別轉換為類別物件,這在強型別語言中屬特例行為,易導致非預期轉換。

隱式轉換範例

class MyClass {
public:
    MyClass(int num); // 非 explicit
};
MyClass obj = 10; // OK:編譯器隱式轉換 int → MyClass
// 等同於:MyClass temp(10); MyClass obj = temp;

加上 explicit 後

class MyClass {
public:
    explicit MyClass(int num); // 顯式建構函數
};
MyClass obj = 10; // 編譯錯誤:cannot convert 'int' to 'MyClass'
// 必須顯式建構:MyClass obj(10); 或 MyClass obj = MyClass(10);

實務應用場景

標準庫 std::string 的 string(int size) 若非 explicit,string s = 1; 會被誤解為建立大小 1 的字串,而非字元 '1'。宣告為 explicit string(int) 可攔截此類筆誤。反之,string(const char*) 保留隱式轉換以支援 string s = "hello"; 等自然語法。

多建構函數時的 explicit 效果

若類別有多個建構函數,explicit 僅影響被修飾的那個。編譯器仍會嘗試其他非 explicit 建構函數進行隱式轉換。

class isbn_mismatch : public std::logic_error {
public:
    explicit isbn_mismatch(const std::string& s) : std::logic_error(s) {}
    isbn_mismatch(const std::string& s, const std::string& lhs, const std::string& rhs)
        : std::logic_error(s), left(lhs), right(rhs) {} // 非 explicit
    const std::string left, right;
    virtual ~isbn_mismatch() throw() {}
};
// 拋出時:throw isbn_mismatch("isbn mismatch", lhs.book(), rhs.book()); // 呼叫非 explicit 版

標準建議

《ANSI/ISO C++ Professional Programmer's Handbook》建議:單一參數建構函數預設應加 explicit,除非隱式轉換符合領域邏輯且行為良好(如智慧指標、字串字面值轉換)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved