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

C++ 類型轉換全景:隱式/顯式、轉換構造函數、類型轉換函數、標準轉換運算符

     編輯:關於C++

1. 標量類型隱式轉換

int i = 6;
i = 4.5 + i;  // 警告:double → int 截斷
// 過程:i→double → 相加 → 10.5 → 截斷為 10 → 賦值給 i

編譯器自動插入轉換,可能丟失精度/符號,建議開啟警告 -Wconversion。

2. 標量類型顯式轉換

int(11.1)     // 函數式風格
static_cast(11.1)  // C++ 風格,推薦
(int)11.1     // C 風格,不推薦

3. 轉換構造函數:其他類型 → 類對象

定義

單參數構造函數(或除第一參數外全有默認值),隱式用於類型轉換。

class Complex {
    double re, im;
public:
    Complex(double r, double i) : re(r), im(i) {}      // 初始化構造
    Complex(double r) : re(r), im(0) {}                // 轉換構造:double → Complex
};

應用場景

Complex c(0,0);
c = c + 2.5;  // 錯誤:無 operator+(Complex, double)

// 方案 A:重載 operator+(double)
Complex operator+(double r) const { return Complex(re+r, im); }

// 方案 B:利用轉換構造函數
Complex operator+(const Complex& rhs) const { return Complex(re+rhs.re, im+rhs.im); }
Complex c1(2.5);  // 隱式轉換
c = c + c1;       // 調用 operator+(Complex)

跨類轉換

class Teacher {
public:
    Teacher(const Student& s) {  // Student → Teacher
        num = s.num; name = s.name; sex = s.sex;
    }
};

4. 類型轉換函數:類對象 → 其他類型

定義

class Complex {
    double re, im;
public:
    operator double() const { return re; }  // Complex → double
    // 無返回類型、無參數、隱式調用
};

效果

Complex c(3.0, 4.0);
double d = c + 2.5;  // c → double(3.0) → 3.0+2.5=5.5 → d=5.5

5. 標準轉換運算符 (C++11)

explicit 轉換函數

class Ptr {
    int* p;
public:
    explicit operator bool() const { return p != nullptr; }  // 僅在布爾上下文隱式調用
};
Ptr ptr = ...;
if (ptr) { ... }        // OK
int x = ptr;            // Error
int y = ptr + 1;        // Error

防止意外算術轉換,保留條件判斷語義。

刪除轉換函數

class NonConvertible {
public:
    operator int() const = delete;  // 禁止轉換為 int
};

6. 總結對比

機制方向隱式性定義位置典型用途
隱式標量轉換內建類型間自動語言內建數值運算混合類型
顯式轉換內建類型間程序員指定使用點明確意圖、窄化轉換
轉換構造函數其他 → 類隱式(非 explicit)目標類數值包裝、字面值構造
類型轉換函數類 → 其他隱式(非 explicit)源類智能指針 bool、數值提取
explicit 轉換函數類 → 其他僅語境隱式源類安全布爾、受控轉換

最佳實踐

  1. 單參數構造函數默認 explicit,除非確需隱式語義(如 string(const char*))。
  2. 類型轉換函數慎用,優先提供命名成員函數(toDouble())。
  3. C++11 起優先用 explicit operator bool() 實現安全布爾語境。
  4. 避免雙向隱式轉換導致歧義(A→B 和 B→A 同時存在)。
  5. 標準庫算法/容器操作常觸發隱式轉換,注意性能與語義。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved