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

C++ explicit 關鍵字:禁止構造函數隱式類型轉換

     編輯:關於C++

隱式轉換問題

單參數構造函數(或除第一參數外均有默認值)會定義隱式轉換:

class B {
public:
    B(int x);          // 可隱式 int -> B
    void doSomething(B b);
};
B obj;
obj.doSomething(20);   // 20 隱式轉換為 B(20) 再傳入

這可能導致意外行為(如非預期的臨時對象創建、性能損耗、語義錯誤)。

explicit 關鍵字

在構造函數聲明前加 explicit 禁止隱式轉換:

class B {
public:
    explicit B(int x); // 禁止 int -> B 隱式轉換
    void doSomething(B b);
};
obj.doSomething(20);   // 編譯錯誤:無隱式轉換
obj.doSomething(B(20)); // 必須顯式構造

規則與最佳實踐

  • explicit 只能用於類內部構造函數聲明,不能用於類外定義。
  • Google C++ 風格指南:所有單參數構造函數應聲明為 explicit,極少數例外(如透明包裝器)。
  • Effective C++ 條款:除非有充分理由允許隱式轉換,否則加 explicit。防止編譯器執行「非預期、往往也不被期望」的類型轉換。
  • 拷貝構造函數通常不加 explicit(需支持按值傳遞/返回),但 C++11 起可加 explicit 禁止隱式拷貝(罕見)。

代碼示例

class Widget {
public:
    explicit Widget(int id);           // 禁止 int -> Widget
    explicit Widget(const string& name); // 禁止 string -> Widget
    Widget(const Widget&) = default;   // 拷貝構造通常不加 explicit
    Widget& operator=(const Widget&) = default;
};
void process(Widget w);
int main() {
    process(10);       // 錯誤:隱式轉換被禁止
    process(Widget(10)); // 正確:顯式構造
    process("name");   // 錯誤
    process(Widget("name")); // 正確
}

總結

  • explicit 是防止構造函數成為隱式轉換運算子的關鍵機制。
  • 默認加 explicit,需要隱式轉換時再考慮移除(極少)。
  • 提高代碼安全性、可讀性,避免驚人的隱式行為。

掌握 explicit 是編寫健壯 C++ 類的基本功,體現「顯式優於隱式」的現代 C++ 設計哲學。

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