代碼場景
Object& MyFunction(int b, int a = 20) {
Object* o = new Object;
o->a = a; o->b = b;
return *o; // 為什麼是 *o 而不是 o 或 &o?
}
類型推導表
| 表達式 | 類型 | 含義 | 能否作為 `Object&` 返回 |
| `o` | `Object*` | 指針地址 | ❌ 類型不匹配 |
| `&o` | `Object**` | 指針變量的地址 | ❌ 類型不匹配 |
| `*o` | `Object` | 指針指向的**對象實體** (左值) | ✅ 完美匹配 `Object&` |
內存圖解
棧幀 MyFunction:
o (Object*) ──────► 堆: Object { a=20, b=5 } ← *o 代表這個對象
- 函數返回類型 `Object&` 承諾:**返回一個已存在 Object 的別名**。
- `*o` 解引用指針,得到該對象實體,編譯器將其作為引用返回給調用者。
- 調用端 `Object& r = MyFunction(5);` 綁定到同一堆對象。
關鍵陷阱:懸空引用
Object& bad() {
Object local; // 棧上對象
return local; // ❌ 函數結束 local 銷毀,引用懸空
}
Object& good() {
static Object single; // 靜態存儲區,生命週期 = 進程
return single; // ✅ 安全
}
Object& good2() {
Object* p = new Object; // 堆對象,手動管理
return *p; // ✅ 安全,但調用者必須 delete &r
}
現代 C++ 建議:避免裸指針 + 手動 delete
#include
// 返回智能指針,所有權清晰
std::unique_ptr
原代碼完整修正版
#include
using namespace std;
struct Object { int a; int b; };
Object& MyFunction(int b, int a = 20) {
Object* o = new Object;
o->a = a; o->b = b;
return *o; // 返回堆對象引用
}
int main() {
Object& rMyObj = MyFunction(5); // a=20(默認), b=5
cout << "rMyObj.a=" << rMyObj.a << ", b=" << rMyObj.b << endl;
delete &rMyObj; // 必須手動釋放堆內存
return 0;
}