首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 運算符重載:加法正常減法卻顛倒?解決方案詳解

     編輯:程式設計疑難解答

問題背景

在實現貨幣類 RMB 的運算符重載時,發現加法運算正常,但減法運算結果卻出現「兩個數反過來減」的現象。經分析,原因在於減法運算符內部修改了左操作數的成員變量,導致後續計算使用了已被改變的值。

錯誤代碼片段

RMB RMB::operator -(RMB b) {
    if (fen < b.fen) { // 借位邏輯
        if (jiao > 0) {
            fen += 10;
            jiao--;
        } else if (yuan > 0) {
            yuan--;
            jiao += 9;
            fen += 10;
        }
    }
    fen -= b.fen;
    if (jiao < b.jiao) { // 借位邏輯
        if (yuan > 0) {
            yuan--;
            jiao += 10;
        }
    }
    jiao -= b.jiao;
    yuan -= b.yuan;
    return RMB(yuan, jiao, fen);
}

根本原因

在 operator- 中直接修改了 this 對象的 yuan、jiao、fen,導致左操作數(即調用對象)的狀態被改變。當後續執行 f = d - c 時,c 已經被之前的 e = c + d 改變(因為加法同樣修改了左操作數),從而導致減法使用了錯誤的數值。

正確做法

  1. 運算符重載應保持左操作數不變,採用「創建臨時對象」的方式進行計算。
  2. 將借位邏輯封裝在輔助函數中,避免重複代碼。
  3. 建議同時重載 operator+= 和 operator-=,再基於它們實現 operator+ 和 operator-。

修正後的減法示例

RMB RMB::operator -(const RMB& b) const {
    int ny = yuan, nj = jiao, nf = fen;
    // 借位處理
    if (nf < b.fen) {
        if (nj > 0) { nf += 10; nj--; }
        else if (ny > 0) { ny--; nj += 9; nf += 10; }
    }
    nf -= b.fen;
    if (nj < b.jiao) {
        if (ny > 0) { ny--; nj += 10; }
    }
    nj -= b.jiao;
    ny -= b.yuan;
    return RMB(ny, nj, nf);
}

總結

運算符重載時切勿修改左操作數,應返回新對象。遵循此原則可避免加法正常而減法異常的問題,確保運算邏輯正確可靠。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved