int a = 12;
int& ra = a; // ra 是 a 的別名
--ra; // a 變 11
a = 10; // ra 變 10
int* ip = &ra; // 取址得 a 的地址
參考不是指標,雖然編譯器常以指標實現,但語意與行為截然不同。
| 特性 | 參考 | 指標 |
|---|---|---|
| 空值 | 不存在空參考 | 可為 nullptr |
| 初始化 | 宣告時必須初始化 | 可延遲初始化 |
| 重新綁定 | 一生綁定初始化物件,不可改變 | 可隨時指向其他物件 |
雖然語法不允許空參考,但透過解參考空指標可製造:
Employee& ref = *static_cast<Employee*>(0); // 編譯器可能檢測
Employee* getEmp();
Employee& ref = *getEmp(); // 危險!若回傳 nullptr → UB
if (&ref == 0) ... // 檢查無意義,UB 已發生
正確做法:
Employee* emp = getEmp();
if (emp) { /* 使用 *emp 或 Employee& ref = *emp; */ }
template<typename T>
void swap(T& a, T& b) {
T tmp(a); a = b; b = tmp;
}
int x=1, y=2; swap(x, y); // a 是 x 別名,b 是 y 別名,無拷貝開銷
參考賦予無名物件(如陣列元素 arr[i])方便別名:
float& r = a[i*m + j];
r = r * r + r; // 簡化複雜索引運算,且避免重複計算
const double& cd = 12.3; // 綁定臨時 double
const std::string& s = foo() + bar(); // 綁定運算式產生的臨時物件
// 臨時物件壽命延長至參考離開作用域
非 const 參考不可綁定臨時物件/字面值:
double& d = 12.3; // 錯誤
swap(std::string("a"), std::string("b")); // 錯誤
const T& 傳遞大型物件,需修改用 T&,避免指標語意模糊。