首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++ this 指標深度解析:存在與否、實現機制與記憶體模型

     編輯:C++ 入門

前言:帶著問題理解 this

作者透過 6 個層層遞進的問題,從「this 是什麼」深入到「實現機制」,最終揭示 this 既存在又不存在 的辯證本質。

六大核心問題與解答

Q1: this 指標是什麼?

非靜態成員函數的隱含參數,指向調用該函數的物件實例。

Q2: 為什麼叫 this?

英文「this」意指「這個」,暗示僅在類別內部可見,代表「這個類別的這個物件」。

Q3: this 幹嘛的?

成員變數/函數存取實際上均為 this->member。編譯器自動插入 this,程式碼可寫可不寫。

Q4: this 有空間嗎?在哪?

有。this 本質是指標 (機器碼層面為暫存器/棧上值),儲存物件位址。

  • new 出的物件:this 值在堆區 (物件位址)。
  • 棧上物件:this 值在棧區 (物件位址)。

Q5: this 在哪用?

類別內部所有非靜態成員存取。範例:


class A {
    int v;
    void f() { this->v = 1; } // 等價 v = 1;
};

Q6: this 實現機制?

核心揭秘:編譯器將 this 作為第一個隱含參數傳遞給成員函數 (通常放 ECX (MSVC thiscall) 或 RDI (System V AMD64) 暫存器)。

反組證實驗 (MSVC x86)


// 原始碼
class Test { int a; void foo() { a = 1; } };
Test t; t.foo();

// 反組譯關鍵段
01351041  mov         ebp, esp        ; 建立堆疊幀
01351047  mov         eax, [ebp-4]    ; 取得 this (物件位址 ebp-4)
0135104A  mov         dword ptr [eax], 1 ; this->a = 1
  • ebp-4 為物件在棧上位址 (即 this 值)。
  • eax 載入該位址,隨後解引用存取成員。
  • 機器碼中完全沒有名為 this 的符號,只有位址傳遞與解引用。

辯譟:this 到底存不存在?

視角結論理由
源碼/語言語義存在C++ 標準定義非靜態成員函數有隱含 this 參數,可在程式碼中顯式使用 this->。
機器碼/執行時不存在無 this 符號、無額外記憶體儲存 this,只有暫存器/棧上傳遞的物件位址。
實現本質位址傳遞約定編譯器約定:調用者將物件位址置於特定暫存器/棧位,被調用者以此定址成員。

關鍵結論

  1. this 不是成員變數,不佔用物件大小 (sizeof(Test) == 4 不含 this)。
  2. this 是右值,不可取址 (&this 錯誤),不可修改。
  3. 靜態成員函數無 this,因不屬於特定物件。
  4. 多重繼承/虛繼承 下,this 指標調整 (thunk) 更複雜,但本質仍是「物件位址傳遞」。

實務啟示

  • 理解 this 為「隱含參數」有助於理解 const 成員函數 (this 變為 const Test* const)。
  • 避免在建構函數中將 this 傳遞給其他執行緒/回調 (物件未完全建構)。
  • CRTP (Curiously Recurring Template Pattern) 利用 static_cast(this) 實現靜態多態。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved