首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

C++ 指針完全指南:從對象指針到 this、成員指針與 const 語義

     編輯:更多程式設計知識

前言

指針是 C++ 核心也是難點。本文系統梳理 C++ 中五大指針類型:**對象指針、成員指針、this 指針、常指針、指向常量的指針**,結合內存模型圖解與代碼實戰,助你徹底掌握指針語義、避開懸空、野指針、const 陷阱。

1. 對象指針

定義與賦值

class Time { public: int h,m,s; void show(); };
Time t;          // 棧上對象
Time* p = &t;    // p 指向 t
Time* q = new Time; // 堆上對象,需 delete q

訪問成員

  • `(*p).h` 或 `p->h` (數據成員)
  • `(*p).show()` 或 `p->show()` (成員函數)

關鍵點

  • 對象指針存儲對象**起始地址**。
  • 多態基礎:基類指針指向派生對象,配合 `virtual` 實現動態綁定。
  • **規則**:`delete` 必須配對 `new`,`delete[]` 配對 `new[]`,避免內存洩漏/未定義行為。

2. 成員指針

數據成員指針

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)();      // 指針調用

語法規則

  • **聲明**:`返回類型 (類名::*指針名)(參數列表)`
  • **取址**:`&類名::成員名`(不加 `()`,區別於普通函數指針)。
  • **調用**:對象用 `.*`,指針用 `->*`。
  • **用途**:回調表、序列化框架、屬性映射(如 ORM、反射模擬)。

3. this 指針

本質

  • 非靜態成員函數的**隱式參數**,類型為 `ClassName* const` (指向對象的常指針)。
  • 指向調用該函數的**具體對象實例**。

編譯器視角

// 源碼
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)

常見用法

  1. 區分同名參數/成員:`this->val = val;`
  2. 鏈式調用返回 `*this`:`return *this;`
  3. 傳遞當前對象給其他函數:`other.registerObserver(this);`
  4. **不能在構造函數初始化列表/靜態成員函數中使用**。
  5. 4. 常指針 vs 指向常量的指針

    類型聲明指針值可變?指向值可變?典型場景
    常指針`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,極度不推薦)

    5. 指向常對象的指針

    
    const Time t1(8,8,8);   // 常對象
    const Time* p = &t1;    // 必須用指向常量的指針
    p = &t2;                // 合法:改變指向
    // p->h = 9;            // 編譯錯誤:不能修改常對象成員
    

    核心價值:構建 **const 正確性** 體系,編譯期捕獲誤寫,優化器可假設只讀進行更激進優化。

    避坑清單

    1. 懸空指針:返回局部對象地址、`delete` 後未置空、容器重新分配導致迭代器/指針失效。
    2. 野指針:未初始化指針、`malloc`/`new` 失敗未檢查。
    3. const_cast 濫用:去除 const 修改原為常量的對象 → 未定義行為。
    4. 多態刪除:基類析構函數**必須聲明 virtual**,否則 `delete basePtr` 僅調用基類析構,派生資源洩漏。
    5. 智能指針優先:現代 C++ (C++11+) 首選 `std::unique_ptr`、`std::shared_ptr`,RAII 自動管理生命週期,裸指針僅用於觀察者、非擁有語義、C 接口互操作。

    總結

    指針是 C++ 控制內存、實現多態、構建高性能數據結構的基石。理解 **指針類型** (`T*`, `T* const`, `const T*`) 與 **指向類型** 的區別、掌握 `this` 隱式傳遞機制、熟練使用成員指針進行元編程,並堅持「智能指針優先、const 正確性、RAII 資源管理」,即可駕馭指針威力並規避 90% 常見崩潰風險。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved