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

C++ Primer 學習筆記:重載運算符與轉換——類類型轉換函數詳解

     編輯:C++ 入門

類類型轉換:兩種形式

  1. 轉換構造函數:單參數構造函數(非 explicit),實現 其他類型 → 類類型 的隱式轉換。
  2. 轉換運算符:operator type(),實現 類類型 → 其他類型 的隱式轉換。

轉換構造函數

class SmallInt {
public:
    SmallInt(int i = 0) : val(i) {  // 非 explicit,允許隱式轉換
        if (i < 0 || i > 255) throw out_of_range("Bad SmallInt value");
    }
private:
    std::size_t val;
};

// 用法:
SmallInt si = 42;        // 隱式調用 SmallInt(42)
si = 3;                  // 隱式調用 SmallInt(3) 然後賦值
if (si) { ... }          // 隱式轉換為 bool(需定義 operator bool)

explicit 關鍵字(C++11)

  • explicit SmallInt(int i = 0); 禁止隱式轉換,僅允許直接初始化:SmallInt si(42);、SmallInt si = SmallInt(42);。
  • 最佳實踐:單參數構造函數默認加 explicit,除非確有隱式轉換語義需求(如智能指針、包裝類型)。
  • C++11 允許 explicit 轉換運算符,僅在直接初始化、靜態轉換、條件表達式中生效。

轉換運算符

class SmallInt {
public:
    operator int() const { return val; }  // 隱式轉換為 int
    explicit operator bool() const { return val != 0; }  // C++11:僅用於條件判斷
private:
    std::size_t val;
};

// 用法:
int i = si;           // 隱式調用 operator int()
bool b = si;          // 調用 explicit operator bool(),允許在 if、while、!、? : 中
// long l = si;       // 錯誤:無隱式轉換為 long(需轉換為 int 再提升)

避免雙向隱式轉換陷阱

若類 A 有接受 B 的轉換構造,B 有轉換為 A 的運算符,會導致歧義:

struct A { A(const B&); };
struct B { operator A() const; };
void f(A);
B b; f(b);  // 錯誤:歧義,既可 A(b) 也可 b.operator A()

解決策略

  • 盡量單向提供隱式轉換。
  • 使用 explicit 封鎖不必要的方向。
  • 提供顯式命名函數(如 to_string()、as_int())替代隱式轉換。

標準庫中的轉換設計

  • std::string:explicit 構造自 const char*(C++11 起),但提供 c_str() 顯式獲取 C 字符串。
  • std::shared_ptr:explicit operator bool(),支持 if (ptr) 但禁止 int i = ptr;。
  • std::chrono::duration:提供顯式轉換構造與 count() 成員,避免單位混淆。

總結

  1. 轉換構造(其他→類):單參數構造,默認 explicit,除非建模語義要求隱式。
  2. 轉換運算符(類→其他):operator type(),條件判斷類型用 explicit operator bool()。
  3. 避免雙向隱式導致歧義;優先提供顯式命名轉換函數。
  4. 標準庫是最佳參考:string、shared_ptr、chrono 均採用顯式為主、隱式為輔的設計。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved