靜態類型語言的核心目標
恰當操作數據,得到期望值。需要:
- 定義數據類型:數據是什麼(int/float/char/自定義),值範圍
- 定義操作含義:操作嚴格依賴類型,確定輸入類型→輸出結果
C++ 的類型體系
內置類型
- 基本類型:整數、浮點、布爾、字符...
- STL 庫類型:iostream、string、迭代器...
- 復合類型機制:引用、指針、數組——可作為完整類型一部分
- 修飾符:const、static、volatile... 定義數據額外屬性
自定義類型
- class/struct/union 定義
- 函數簽名(函數類型)
- 復合類型機制應用於自定義類型
操作的廣義含義
C++ 中一切操作本質都是函數:
- 操作符:算術、關係、位運算、取址、解引用、下標...
- 拷貝操作:拷貝初始化、列表初始化、賦值、函數傳參/返回、隱式轉換產生的臨時對象拷貝
- 類型轉換:提升、降級、標準轉換、用戶定義轉換
- 成員函數、友元函數:對類類型的操作
- 函數指針、成員指針:操作本身作為數據類型
類型轉換的本質
操作期待特定類型操作數,實際類型不匹配時,編譯器插入類型轉換操作:
int n = 42; double f = 3.14;
double r = f + n; // n 隱式轉換為 double(生成匿名臨時變量)
賦值同理:右值轉換為左值類型後再拷貝。函數調用:實參轉換為形參類型。
C++ 複雜轉換規則精要
- 整型提升:char/short/bool → int
- 類型提升:防精度損失(float→double)
- 類型降級:有精度損失,常見於拷貝(double→int)
- 非 bool → bool(0→false,非0→true)
- 任意指針 → void*
- 數組退化:非常數表達式上下文 → 首元素指針
- const 轉換:非底層 const → 底層 const 合法,逆向非法
- 繼承轉換:派生 → 基類合法(基類指針/引用指向派生),逆向非法
單向轉換的本質原因
操作集合包含關係決定轉換方向:
- 類型 A 支持操作 {opA..opZ},類型 B 支持子集 {opH..opN}
- B 的引用/指針可綁定 A(B 可接受 A 賦值),因 B 的操作 A 都有
- 逆向非法:A 有 B 沒有的操作,若允許 A→B,調用 B 沒有的操作導致 UB
- 同理:
const int* 操作集 ⊂ int*,故 const int* 可綁定 int* 目標
- 基類操作集 ⊂ 派生類,故基類指針可指向派生對象
重載機制本質
同名多操作 → 編譯期從候選集選最匹配操作(「重載決議」)。類型轉換在運行期(或編譯期常量折疊)執行,與重載決議分離。
總結
C++ 通過「類型+操作」雙重體系,實現了靜態類型語言的核心承諾:編譯期確定操作合法性,運行期高效執行。深入理解類型轉換的單向性、操作的函數本質、重載的編譯期決議,是駕馭 C++ 複雜性的關鍵。