| 特性 | 指針 (Pointer) | 引用 |
|---|---|---|
| 本質 | 存儲地址的變量,獨立內存單元 | 變量的別名,不佔用額外內存(概念上) |
| 初始化 | 可延遲,可為 nullptr | 必須在聲明時初始化,不可為空 |
| 重新綁定 | 可隨時修改指向 p = &b; | 不可重新綁定,終身綁定初始化對象 |
| 賦值語義 | p1 = p2 修改指針指向 | r1 = r2 修改被引用對象的值 |
| sizeof | 指針大小 (4/8 字節) | 被引用類型大小 |
| 多級 | 支持多級 int** | 無多級引用 int&& 為右值引用(C++11) |
| 數組 | 可指向數組 | 無引用數組(但有引用數組類型 int (&arr)[10]) |
int a = 1024, b = 2048;
int *p1 = &a, *p2 = &b;
p1 = p2; // p1 指向改變,指向 b
// a 仍為 1024,b 為 2048
// p1 == p2 == &b
int a = 1024, b = 2048;
int &r1 = a, &r2 = b;
r1 = r2; // 相當於 a = b
// a 變為 2048,b 仍為 2048
// &r1 仍是 &a,&r2 仍是 &b(地址未變)
| 聲明 | 含義 | 指針對應 |
|---|---|---|
const int &r = a; | 引用常量,不可通過 r 修改 a | const int *p = &a; |
int &const r = a; | 語法錯誤,引用本身恒為 const | int *const p = &a; (常量指針) |
const int &const r = a; | 語法錯誤 | const int *const p = &a; |
結論:引用天生「常量指針」語義(不可改指向),加 const 只能修飾被引用對象(如 const int&)。
需要修改實參值?
├── 否 → 需要避免拷貝大對象?
│ ├── 是 → const T& (首選) / const T* (需表達可空)
│ └── 否 → 傳值 (T) / const T& (小類型傳值更快)
└── 是 → 需要表達「可空」語義?
├── 是 → T* (調用端可傳 nullptr)
└── 否 → T& (調用端必須傳有效對象,語義更清晰)
void Swap(int &a, int &b) — 必須用引用,指針版 Swap(&a, &b) 易出錯且語義模糊。std::unique_ptr Create() (現代 C++) / T* Create() (C 風格) — 引用無法表達「無對象/失敗」。T& operator=(const T&)、bool operator==(const T&) — 引用是標準規範。編譯器通常將引用實現為常量指針(T* const)。
// 源碼
void Func(int &r) { r = 10; }
int a; Func(a);
// 編譯器視角等價於
void Func(int *const r) { *r = 10; }
int a; Func(&a);
但語義上引用更安全:無空值、無指針運算、無解引用符號、自動解引用。
const T& 輸入,T& 輸出/輸入輸出)。unique_ptr, shared_ptr)替代裸指針管理動態內存所有權。T&&)實現移動語義、完美轉發。T* 傳遞數組(退化失去長度)、T*& 輸出指針(用 std::optional 或返回智能指針)。指針是內存操作的基石,提供極致靈活性與危險;引用是針對「別名」場景的語法糖,提供安全性與可讀性。現代 C++ 核心準則:**默認用引用,需要可空/所有權轉移/動態分配時用智能指針,極少直接用裸指針。**