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

《深度探索 C++ 物件模型》讀書筆記(4):成員函數、虛函數表、Thunk 與指標

     編輯:關於C++

非靜態成員函數

編譯器內部轉換為同效能的非成員函數:

float Point3d::magnitude() const { ... }
// →
float magnitude_7Point3dFv(const Point3d* this) { ... }
obj.magnitude(); // → magnitude_7Point3dFv(&obj)

Name mangling 編碼參數型別確保連結期型別安全 (不含回傳型別)。

虛函數與虛表

  • 物件非多態使用時,編譯器直接決議具體函數 (如 normalize_7Point3dFv)。
  • 多態呼叫 ptr->z() 轉為 (*ptr->vptr[4])(ptr)。
  • 虛表內含:類別自定義函數、繼承未覆寫函數、pure_virtual_called 佔位。

靜態成員函數

  • 無 this 指標,位址型別為普通函數指標 unsigned int (*)(),常用作回呼。
  • 內部呼叫時編譯器傳入 (Class*)0 滿足呼叫慣例。

多重繼承下的虛函數與 Thunk

問題:經由第二基類指標呼叫虛函數需調整 this。

  • 方案 A:虛表槽擴充為 {offset, faddr},所有虛呼叫付出額外開銷。
  • 方案 B (Thunk):小組合語言片段調整 this 再跳轉。虛表槽存 Thunk 位址,無調整需求的函數直接存函數位址。
pbase2_dtor_thunk:
    this += sizeof(Base1);
    Derived::~Derived(this);

虛繼承下的虛函數

機制極度複雜,建議:虛基類**不宣告非靜態資料成員**。

成員函數指標

  • 非虛函數:真實位址。
  • 虛函數:虛表索引值。
  • 呼叫轉換:(*ptr->vptr[(int)pmf])(ptr)。
  • 區分方式:cfront 以數值大小判斷 (假設虛函數 < 128)。

多重/虛繼承下的成員函數指標結構

struct _mptr {
    int delta;      // this 調整位移
    int index;      // 虛表索引 (-1 表非虛)
    union { ptrtofunc faddr; int v_offset; };
};

Inline 函數展開

  • 參數以臨時物件避免多次求值副作用。
  • 區域變數產生大量臨時物件,展開多次時代價放大。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved