引用是變量的別名。就像「蘿卜頭」是「羅XX」的外號,操作別名就是操作本體。引用在定義時必須初始化,且一旦綁定不可改變指向對象。
int a = 3;
int &b = a; // b 是 a 的引用
b = 10; // 實際修改了 a
cout << a; // 輸出 10
關鍵點:引用不是新對象,不佔用額外存儲空間 (編譯器內部通常用指針實現),是編譯時期的語法糖。
struct Coor { int x, y; };
Coor c1;
Coor &c = c1; // c 是 c1 的別名
c.x = 10; c.y = 20;
cout << c1.x << c1.y; // 10 20
結構體引用避免了整體拷貝,語法比指針更直觀 (c.x vs p->x)。
語法:類型 *&引用名 = 指針變量;
int a = 10;
int *p = &a;
int *&q = p; // q 是指針 p 的引用
*q = 20; // 修改 a 為 20
// 等價於 *p = 20
用途:函數參數傳遞指針並允許修改指針本身 (如鏈表頭插法、內存分配函數)。
void swap(int *a, int *b) {
int t = *a; *a = *b; *b = t;
}
swap(&x, &y); // 調用處需取地址
void swap(int &a, int &b) {
int t = a; a = b; b = t;
}
swap(x, y); // 調用處如同傳值,實為傳引用
優勢:
& 取地址。*。const 引用 (延長生命週期)。void print(const string &s) { cout << s; }
// 可接受:字符串字面值、臨時對象、const/非const 字符串
print("hello"); // 臨時 const char[] -> string 臨時對象 -> 綁定 const 引用
print(string("world"));
對於非基本類型參數,優先使用 const 引用:避免拷貝開銷,保護原對象不被修改,接受廣泛參數類型。
int& getElement(vector& v, int i) { return v[i]; }
getElement(vec, 0) = 42; // 左值賦值,修改 vec[0]
禁忌: 絕不返回局部變量/臨時對象的引用 (懸空引用,未定義行為)。
void process(string&& rval) { /* 接管資源 */ }
process(string("temp")); // 綁定右值
process(std::move(str)); // 將左值轉為右值引用
右值引用 (&&) 綁定到將要銷毀的對象,實現資源轉移而非拷貝,是高性能 C++ 的核心機制。
| 類型 | 語法 | 典型用途 | 關鍵限制 |
|---|---|---|---|
| 左值引用 | T& | 函數參數/返回值、別名 | 必須初始化、不可重綁定、不可綁定右值(非常量) |
| const 左值引用 | const T& | 通用輸入參數 | 不可修改對象、可綁定右值/臨時對象 |
| 右值引用 | T&& | 移動構造/賦值、完美轉發 | 僅綁定右值、通常配合 std::move |
| 指針引用 | T*& | 修改指針本身的函數參數 | 較少見、語法晦澀 |
for (auto& x : v) 修改元素,for (const auto& x : v) 僅讀。[&] 引用捕獲,[=] 值捕獲,注意生命週期。掌握引用類型,是寫出高效、安全、現代 C++ 代碼的基石。