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

C++ 運算符重載完全指南:規則、最佳實踐與代碼範例

     編輯:關於C++

運算符重載核心規則

運算符重載本質上是函數重載,必須遵循以下基本原則:

  • 至少一個參數為用戶定義類型(類/結構體/枚舉)
  • 不能改變運算符的優先級、結合性、操作數個數
  • 不能創建新運算符,只能重載現有運算符
  • .、.*、::、?:、sizeof、typeid、alignof 不可重載

成員函數 vs 非成員函數選擇策略

運算符類別推薦形式強制要求
一元運算符 (++、--、! 等)成員函數-
=、()、[]、->、->*成員函數必須為成員
複合賦值 (+=、-= 等)成員函數-
二元算術/比較/邏輯運算符非成員函數 (常配合 friend)-
流運算符 <<、>>非成員 friend左操作數為流對象

關鍵重載模式詳解

前置/後置遞增遞減

class Integer {
    int val;
public:
    // 前置 ++i:返回引用,無額外參數
    Integer& operator++() { ++val; return *this; }
    // 後置 i++:int 佔位參數區分,返回舊值副本
    Integer operator++(int) { Integer tmp(*this); ++val; return tmp; }
    // -- 同理
};

賦值運算符:自賦值檢查與異常安全

class String {
    char* data;
    size_t len;
public:
    String& operator=(const String& rhs) {
        if (this != &rhs) { // 自賦值檢查
            char* newData = new char[rhs.len + 1];
            strcpy(newData, rhs.data);
            delete[] data;
            data = newData;
            len = rhs.len;
        }
        return *this;
    }
    // C++11 移動賦值
    String& operator=(String&& rhs) noexcept {
        if (this != &rhs) {
            delete[] data;
            data = rhs.data; len = rhs.len;
            rhs.data = nullptr; rhs.len = 0;
        }
        return *this;
    }
};

下標運算符:雙版本支持 const 正確性

template <typename T, size_t S>
class Array {
    T data[S];
public:
    T& operator[](size_t i) { return data[i]; }
    const T& operator[](size_t i) const { return data[i]; }
};

流輸出運算符:友元非成員實現

template <typename T, size_t S>
class Array {
    T data[S];
    friend ostream& operator<<(ostream& os, const Array& arr) {
        for (size_t i = 0; i < S; ++i) os << arr.data[i] << ' ';
        return os << '\n';
    }
};

返回值優化與類型轉換

  • 返回值優化 (RVO/NRVO):直接返回臨時對象 return Integer(a + b); 而非構造命名變量再返回,避免拷貝構造/析構開銷
  • 轉換構造函數:單參數構造函數隱式啟用類型轉換,加 explicit 禁止
  • 轉換運算符:operator int() const { return val; } 實現對象到內置類型轉換
  • 避免雙向隱式轉換:會導致二義性編譯錯誤

最佳實踐總結

  1. 保持語義直觀:a + b 不應修改 a 或 b
  2. 成對重載:== 與 !=、< 與 > 等
  3. 複合賦值作為基礎:a + b 可實現為 a += b 的副本
  4. 優先使用非成員非友元函數增強封裝性
  5. 流運算符、交換函數 swap 等需作為友元或非成員
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved