運算符分類總覽
| 類別 | 運算符 | 結合性 | 說明 |
| 算術 | + - * / % | 左→右 | 二元,整數除法截斷 |
++ -- | 右→左 | 前綴/後綴,副作用不同 |
| 賦值 | = | 右→左 | 右值賦給左值 |
+= -= *= /= %= &= |= ^= <<= >>= | 右→左 | 複合賦值,a+=b ≡ a=a+b (僅求值 a 一次) |
| 關係 | == != < > <= >= | 左→右 | 返回 bool,C++20 新增 <=> 三路比較 |
| 邏輯 | ! && || | !右→左, && ||左→右 | 短路求值,&& 優先級高於 || |
| 位運算 | ~ & | ^ << >> | ~右→左, 其他左→右 | 僅適用整數類型,移位超寬度為 UB |
| 成員訪問 | . -> .* ->* | 左→右 | . 對象,-> 指針,.* 指向成員指針 |
| 其他 | sizeof alignof typeid noexcept | 右→左 | 編譯期運算符 |
| 三元 | ?: | 右→左 | 唯一三元運算符,返回左值可賦值 |
| 逗號 | , | 左→右 | 順序求值,返回最右表達式值 |
關鍵運算符行為深度解析
前綴 vs 後綴 ++/--
int x = 10;
std::cout << x++ << '\n'; // 輸出 10,x 變 11
std::cout << ++x << '\n'; // x 變 12,輸出 12
std::cout << x << '\n'; // 輸出 12
性能:前綴返回引用,後綴需拷貝舊值 (對類類型調用拷貝構造) → 迭代器/類類型優先用前綴。
短路求值保命
if (ptr != nullptr && ptr->isValid()) // ptr 為空時不解引用
if (index >= 0 && index < size && buffer[index] > 0)
運算符重載核心規則
- 不可重載:
:: . .* ?: sizeof alignof typeid noexcept (5 個)。
- 不可改變:優先級、結合性、操作數個數、語法形式。
- 至少一個操作數為用戶定義類型 (類/枚舉),防止改變內建類型語義。
- 推薦形式:
| 運算符 | 成員函數 | 非成員函數 (友元) | 返回類型 |
+ - * / % | ✗ | ✓ (對稱性) | 值類型 |
+= -= *= | ✓ | ✗ | T& |
== != < <=> | ✗ | ✓ | bool/std::strong_ordering |
[] () -> | ✓ | ✗ | 按需 |
++ -- | ✓ | ✗ | 前綴 T&,後綴 T |
<< >> | ✗ | ✓ (左操作數為流) | std::ostream&/std::istream& |
流插入/提取重載標準模式
class Point { int x_, y_; friend std::ostream& operator<<(std::ostream&, const Point&); };
std::ostream& operator<<(std::ostream& os, const Point& p) {
return os << '(' << p.x_ << ',' << p.y_ << ')';
}
std::istream& operator>>(std::istream& is, Point& p) {
char c; return is >> c >> p.x_ >> c >> p.y_ >> c; // 解析 (x,y)
}
常見陷阱與最佳實踐
- 位運算優先級陷阱:
if (flags & MASK == 0) 實為 if (flags & (MASK == 0)) → 必須加括號 if ((flags & MASK) == 0)。
- 邏輯運算符 vs 位運算符:
&& vs &,|| vs | — 前者短路、返回 bool,後者位運算、返回整數。
- 重載
&&/||/, 失去短路/序列點特性 → 絕不重載 這三個運算符。
- 三路比較
<=> (C++20):一鍵生成 == != < <= > >=,優先實現 auto operator<=>(const T&) const = default;。
- 轉換運算符
explicit operator bool():防止隱式轉整數參與算術,配合 if (obj) 安全使用。
C++20/23 新增運算符特性速覽
<=> 三路比較運算符,簡化比較重載。
operator[] 支持多參數:matrix[1,2] (C++23)。
std::format / std::print (C++23) 替代 operator<< 格式化輸出。
- Lambda 靜態
operator() 捕獲包擴展 (C++20)。
- 上一篇文章: C++ 入門核心指南:從 C 到面向對象的思維轉型與避坑精要
- 下一篇文章: Visual Studio 2005 C++/CLI 語法革新:告別雙下劃線,擁抱原生托管互操作
Copyright ©
程式碼之家 All Rights Reserved