++ 和 -- 為一元運算符,各有前置 (++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--
實現邏輯完全對稱,僅將增量改為減量。
run(),避免代碼重複int dummy 或省略參數名重載 ++/-- 的關鍵在於精確把握前置與後置的語義差異:前置返回引用、後置返回副本。通過虛擬 int 參數區分兩者,封裝共用邏輯,可實現高效、符合直覺的運算符行為。這也是 STL 迭代器、智慧指標等核心組件的基礎實現模式。