指針是 C++ 核心也是難點。本文系統梳理 C++ 中五大指針類型:**對象指針、成員指針、this 指針、常指針、指向常量的指針**,結合內存模型圖解與代碼實戰,助你徹底掌握指針語義、避開懸空、野指針、const 陷阱。
class Time { public: int h,m,s; void show(); };
Time t; // 棧上對象
Time* p = &t; // p 指向 t
Time* q = new Time; // 堆上對象,需 delete q
int Time::* pData = &Time::h; // 指向類的數據成員 h
Time t; t.*pData = 10; // 通過對象訪問
Time* pt = &t; pt->*pData = 20; // 通過指針訪問
void (Time::* pFunc)() = &Time::show; // 指向成員函數
(t.*pFunc)(); // 對象調用
(pt->*pFunc)(); // 指針調用
// 源碼
int Box::vol() { return h * w * l; }
// 編譯器展開
int Box::vol(Box* const this) { return this->h * this->w * this->l; }
// 調用 t.vol() 實際為 t.vol(&t)
| 類型 | 聲明 | 指針值可變? | 指向值可變? | 典型場景 |
|---|---|---|---|---|
| 常指針 | `Type* const p = &obj;` | 否 (初始化後不可改向) | 是 | 固定綁定某對象,如引用計數控制塊 |
| 指向常量的指針 | `const Type* p = &obj;` | 是 | 否 (只讀訪問) | 函數參數 `const Type*` 承諾不修改實參 |
| 指向常量的常指針 | `const Type* const p = &obj;` | 否 | 否 | 只讀單例、字符串字面量 |
void f1(int* p); // 實參:非 const int*
void f2(const int* p); // 實參:const int* 或 非 const int* (隱式轉換安全)
// 反向不允許:const int* 實參不能傳給 int* 形參 (需 const_cast,極度不推薦)
const Time t1(8,8,8); // 常對象
const Time* p = &t1; // 必須用指向常量的指針
p = &t2; // 合法:改變指向
// p->h = 9; // 編譯錯誤:不能修改常對象成員
核心價值:構建 **const 正確性** 體系,編譯期捕獲誤寫,優化器可假設只讀進行更激進優化。
指針是 C++ 控制內存、實現多態、構建高性能數據結構的基石。理解 **指針類型** (`T*`, `T* const`, `const T*`) 與 **指向類型** 的區別、掌握 `this` 隱式傳遞機制、熟練使用成員指針進行元編程,並堅持「智能指針優先、const 正確性、RAII 資源管理」,即可駕馭指針威力並規避 90% 常見崩潰風險。