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

深度探索 C++ 對象模型(七):成員函數語義——非靜態、靜態與虛函數的內部運作

     編輯:VC 教學

第四章探討函數語義。C++ 支援三種成員函數:靜態、虛、非靜態。各自調用方式與作用不同,但內部運作機制值得深入理解。

非靜態成員函數:效率迷思與現實

成員函數用於封裝與隱藏資料,但效率是否較外部函數高?

// 外部函數
float magnitude3d(const Point3d* _this) { ... }

// 成員函數
float Point3d::magnitude3d() const { ... }

表面上成員函數直接存取成員,效率似乎較高。實際上編譯器將其轉換為外部函數:

  1. 加入 this 指標參數。
  2. 非靜態資料成員存取改為 this->member。
  3. 函數名稱重整(name mangling)保證唯一性。
// 轉換後偽碼
magnitude3d__7Point3dFv(register Point3d* const this) {
    return sqrt(this->_x * this->_x + this->_y * this->_y + this->_z * this->_z);
}
// 調用轉換
obj.magnitude3d()  -->  magnitude3d__7Point3dFv(&obj);

結論:兩者效率相同(兩個鐵球同時落地)。

靜態成員函數:無 this 指標

  • 不需透過對象調用,無 this 指標。
  • 不能直接存取非靜態成員。
  • 不可聲明為 virtual、const、volatile。
  • 取得地址為函數實際位址(非成員函數指標)。
  • 本質上等同非成員函數,但受類作用域限制。

C++ 引入靜態成員函數解決:靜態資料成員需提供存取函數,但該函數不應綁定於對象。

虛函數:多態的核心機制

虛函數實現執行期多態。模型:

  • 每個類擁有虛函數表,含有效虛函數位址。
  • 對象含指向虛函數表的指標(vptr)。
  • 基類指標可指向派生類對象:Point* ptr = new Point3d;
  • 呼叫 ptr->z() 時,編譯器透過 vptr 查找虛函數表中 z() 的固定索引位置,調用正確實體。

虛函數表構建細節

  • 未覆寫的基類虛函數:位址複製到派生類虛函數表。
  • 每個虛函數在整個繼承體系有固定索引值。
  • 純虛函數條目指向 pure_virtual_called()。

單一繼承下的效率

單一繼承體系中,虛函數機制極高效。判斷類是否支援多態,只需檢查是否有虛函數。

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