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

C++ 重載 operator+ 的正確策略與陷阱

     編輯:VC 教學

使用者定義型別(字串、日期、複數、檔案等)常需重載二元 + 實作串接、附加或合併。雖 C++ 提供多種實作方式,但易產生設計誤解,影響正確性、效能與標準庫相容性。本文分析內建 + 特徵,並介紹正確重載策略。

內建 operator+ 特徵

  • 二元、對稱、可交換:a + b == b + a。
  • 兩運算元型別相同,回傳型別亦相同(右值)。
  • 不修改運算元,無副作用。

重載時應盡量模仿上述語意。

第一步:成員函式 vs 非成員函式

成員函式寫法:

class String {
public:
    bool operator==(const String& s); // 隱含 this 指標,非對稱
};

缺點:兩參數型別不同(const String* const vs const String&),破壞對稱性,導致部分 STL 演算法/容器無法正確處理。

非成員函式寫法(推薦):

String operator+(const String& s1, const String& s2); // 兩參數型別相同

class String {
public:
    friend String operator+(const String&, const String&);
};

優點:對稱、符合內建語意、完美配合 STL。

第二步:回傳值型別抉擇

回傳指標 String*:違反「回傳型別與運算元相同」原則;鏈式運算 s1+s2+s3 無法編譯;需動態配置記憶體,易造成記憶體洩漏。

回傳參考 String&:避免動態配置,但必須回傳有效物件。常見做法回傳區域靜態物件,卻引發多執行緒競爭、狀態殘留等嚴重問題,不可取。

回傳實值 String(推薦):雖有複製成本,但現代編譯器支援 RVO/NRVO(回傳值優化)與 C++11 移動語意,實際開銷極小。最安全、最簡單、符合直覺,且支援鏈式運算。

完整範例

class String {
    char* data;
    size_t len;
public:
    String(const char* s = "");
    String(const String&);
    String(String&&) noexcept;
    ~String();
    String& operator=(const String&);
    String& operator=(String&&) noexcept;

    friend String operator+(const String& lhs, const String& rhs) {
        String res;
        res.len = lhs.len + rhs.len;
        res.data = new char[res.len + 1];
        memcpy(res.data, lhs.data, lhs.len);
        memcpy(res.data + lhs.len, rhs.data, rhs.len + 1);
        return res; // RVO/移動語意消除複製
    }
};

總結

  1. 以 friend 非成員函式實作 operator+,確保對稱性。
  2. 回傳實值型別,配合移動建構函式獲得高效能。
  3. 提供 operator+= 作為基礎,operator+ 可委託給 += 實作,減少代碼重複。
  4. 遵循標準庫慣例,確保與 STL 算法、容器無縫協作。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved