什麼是參考?
參考是**已存在物件的別名**,非獨立物件,**不佔用額外記憶體**(編譯器內部通常用指標實現)。宣告時**必須初始化**,之後**不可重新綁定**。
int a = 10;
int &ref = a; // ref 是 a 的別名
ref = 20; // a 變為 20
cout << a; // 輸出 20
cout << &a << " " << &ref; // 地址相同
參考 vs 指標:核心差異
| 特性 | 參考 | 指標 |
| 初始化 | 宣告時必須綁定 | 可延遲、可為 nullptr |
| 重新綁定 | ❌ 不可 | ✅ 隨時修改指向 |
| 空值 | 不存在「空參考」 | nullptr |
| 語法 | 像物件同樣使用 ref.x | 需解引用 ptr->x |
| sizeof | 被參考物件大小 | 指標大小 (4/8 bytes) |
| 記憶體層級 | 編譯期別名 | 運行期變數 |
const 參考的特殊能力:綁定右值並延長壽命
int a = 10;
// int &r1 = a + 1; // ❌ 非常量參考不能綁定右值
const int &r2 = a + 1; // ✅ const 參考可綁定臨時物件
const int &r3 = 3.14; // ✅ 甚至可綁定不同型別字面值(隱式轉換產生臨時 int)
編譯器內部機制:臨時物質化
const double &ref = a + 1.2f;
// 等價於編譯器生成:
int temp = a; // 隱式轉換
const double &ref = temp + 1.2f; // 綁定臨時 double
// 注意:修改 a 不會影響 ref,因為 ref 綁定的是 temp+1.2f 的結果
**壽命延長規則**:臨時物件壽命延長至參考變數壽命結束(僅限直接綁定,不適用於函數返回參考鏈)。
函數參數傳遞:參考的核心戰場
| 場景 | 推薦 | 理由 |
| 大型物件/不可複製類別 | const T& | 避免拷貝,承諾不修改 |
| 需修改實參 | T& | 輸出參數、修改狀態 |
| 小型可複製類別 (int, pair, span) | 傳值 T | 傳值更快(寄存器)、無別名分析干擾、支援移動語意 |
| 通用代碼/模板 | T&& (通用引用) + std::forward | 完美轉發,保留左/右值屬性 |
經典錯誤:返回區域物件參考
const int& getRef() {
int x = 42;
return x; // ❌ 返回區域變數參考 → 懸空參考,UB
}
int& getStaticRef() {
static int x = 42;
return x; // ✅ static 生命週期覆蓋整個程式
}
現代 C++:右值參考與移動語意
void process(const string& s) { /* 只讀 */ }
void process(string&& s) { /* 可修改/竊取資源 */ }
string getName() { return "temp"; }
process(getName()); // 呼叫 string&& 版本,避免拷貝
process(myString); // 呼叫 const string& 版本
總結
- 參考是**別名**,宣告即綁定、不可重綁、無空值、語法透明。
const T& 可綁定右值並延長臨時物件壽命,是**唯讀函數參數**的標準選擇。
- 小型物件**優先傳值**(C++17 複製消除 + 移動語意),大型/不可複製物件用
const T&。
- 輸出參數用
T&,通用代碼用 T&& + std::forward 完美轉發。
- **嚴禁**返回區域變數參考/指標,靜態/成員/參數物件除外。
- 上一篇文章: C++ 布爾類型深度解析:bool 的隱式轉換、指標語境與整數本質
- 下一篇文章: C++ const 限定符完全指南:從變數常量化到指標多層 const 解讀
Copyright ©
程式碼之家 All Rights Reserved