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

C++ 重載自增/自減運算符 (++/--):前置與後置的正確實現差異

     編輯:C++ 基礎

一元運算符重載的特殊性

++ 和 -- 為一元運算符,各有前置 (++i) 與後置 (i++) 兩種形式,均可重載。關鍵在於區分兩者的語義差異:

  • 前置形式:先增後用,返回增值後的物件引用
  • 後置形式:先用後增,返回增值前的物件副本

語法區分技巧:虛擬 int 參數

C++ 約定以 int 參數標識後置形式(參數本身無實際用途):

// 類內聲明
Type& operator++();      // 前置 ++i
Type operator++(int);    // 後置 i++ (int 為佔位符)

實戰範例:秒表類

#include <iostream>
#include <iomanip>
using namespace std;

class Stopwatch {
public:
    Stopwatch() : m_min(0), m_sec(0) {}
    void setzero() { m_min = 0; m_sec = 0; }
    Stopwatch run();              // 核心邏輯:秒針前進一秒
    Stopwatch& operator++();      // 前置 ++
    Stopwatch operator++(int);    // 後置 ++
    friend ostream& operator<<(ostream&, const Stopwatch&);
private:
    int m_min, m_sec;
};

// 核心邏輯封裝
Stopwatch Stopwatch::run() {
    ++m_sec;
    if (m_sec == 60) { m_min++; m_sec = 0; }
    return *this;
}

// 前置:直接返回 run() 結果(引用)
Stopwatch& Stopwatch::operator++() {
    return run();
}

// 後置:保存舊值,執行 run(),返回舊副本
Stopwatch Stopwatch::operator++(int) {
    Stopwatch old = *this;
    run();
    return old;
}

// 輸出格式化
ostream& operator<<(ostream& out, const Stopwatch& s) {
    out << setfill('0') << setw(2) << s.m_min << ':' << setw(2) << s.m_sec;
    return out;
}

int main() {
    Stopwatch s1, s2;
    s1 = s2++;  // 後置:s1 得到舊值 00:00,s2 變 00:01
    cout << "s1: " << s1 << endl;
    cout << "s2: " << s2 << endl;

    s1.setzero(); s2.setzero();
    s1 = ++s2;  // 前置:s2 先變 00:01,s1 得到新值 00:01
    cout << "s1: " << s1 << endl;
    cout << "s2: " << s2 << endl;
}

運行結果

s1: 00:00
s2: 00:01
s1: 00:01
s2: 00:01

核心實現差異深度解析

特性前置 ++obj後置 obj++
聲明Type& operator++()Type operator++(int)
返回型別引用 Type&值 Type (副本)
語義修改後返回自身返回修改前副本
效能無額外拷貝需建構/拷貝副本
典型實現do_increment(); return *this;Type tmp=*this; do_increment(); return tmp;

自減運算符 (--) 同理

Type& operator--();      // 前置 --obj
Type operator--(int);    // 後置 obj--

實現邏輯完全對稱,僅將增量改為減量。

最佳實踐建議

  1. 優先使用前置形式:迭代器、複雜物件避免不必要的副本建構
  2. 返回型別正確:前置返回引用,後置返回值
  3. 封裝核心邏輯:如例中 run(),避免代碼重複
  4. 後置參數命名:慣用 int dummy 或省略參數名

總結

重載 ++/-- 的關鍵在於精確把握前置與後置的語義差異:前置返回引用、後置返回副本。通過虛擬 int 參數區分兩者,封裝共用邏輯,可實現高效、符合直覺的運算符行為。這也是 STL 迭代器、智慧指標等核心組件的基礎實現模式。

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