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

C++ 動態聯編機制深度解析(上):從多型必要性到物件型別資訊與虛函數表起源

     編輯:關於C++

前言

多型是 C++ 物件導向核心特徵,動態聯編是其技術基石。本文從靜態聯編侷限出發,推導動態聯編必要性,實驗驗證含虛函數物件的額外記憶體佈局,揭示 vptr/vtable 機制起源。

一、聯編概念與靜態聯編侷限

  • 聯編:將函數呼叫與實作位址關聯、分配記憶體位址
  • 靜態聯編:編譯期完成,依指標/參考靜態型別決定
  • 動態聯編:執行期完成,依物件動態型別決定
  • C 語言全靜態聯編;C++ 預設靜態,virtual 觸發動態

二、靜態聯編導致的多型失效


// 1.cpp
class shape { void draw() { cout << "I am shape"; } void fun() { draw(); } };
class circle : public shape { void draw() { cout << "I am circle"; } };

circle oneshape;
oneshape.fun();  // 輸出 "I am shape" ❌

fun() 內呼叫 draw(),編譯期只知 this 為 shape*,靜態聯編至 shape::draw()。

三、virtual 關鍵字喚醒動態聯編


// 2.cpp
class shape { virtual void draw() { cout << "I am shape"; } void fun() { draw(); } };
class circle : public shape { void draw() { cout << "I am circle"; } };

circle oneshape;
fun(&oneshape);  // 輸出 "I am circle" ✅

基類 virtual 宣告 → 編譯器安裝動態聯編機制 → 執行期依物件型別分派。

四、動態聯編機制推測:物件內建「身份證」

編譯期不知具體衍生類型 → 必須在物件內嵌入型別資訊 → 執行期查閱分派。

五、實驗驗證:虛函數帶來的記憶體開銷


// 3.cpp
class shape_novirtual { int a; void draw(); };
class shape_virtual1 { int a; virtual void draw(); };
class shape_virtual2 { int a; virtual void draw(); virtual void draw1(); };

sizeof(int)           → 4
sizeof(shape_novirtual) → 4  (僅 int a)
sizeof(void*)         → 4  (指標大小)
sizeof(shape_virtual1)  → 8  (+4 bytes = 1 個指標)
sizeof(shape_virtual2)  → 8  (+4 bytes = 仍為 1 個指標)

結論:含虛函數類別物件額外增加 1 個指標大小 (vptr),不隨虛函數數量增長。

六、空類別大小特例


class empty_novirtual {};  // sizeof = 1 (C++ 禁止零大小物件)
class empty_virtual { virtual void f(); };  // sizeof = 4 (vptr)

無成員變數時,編譯器插入 1 byte 佔位符;有虛函數則以 vptr 取代佔位符 (對齊到指標大小)。

七、動態聯編完整流程預覽

  1. 編譯期:含虛函數類別 → 建立 vtable (函數位址表) → 類別插入 vptr
  2. 建構期:物件初始化 vptr 指向自類別 vtable
  3. 呼叫期:this->virtual_func() → 編譯為 call this->vptr[index]
  4. 執行期:this 實際型別決定 vtable → 正確函數位址 → 動態分派

八、下篇預告

下篇將詳細剖析:vtable 具體佈局、衍生類別 vtable 繼承規則、編譯器靜態/動態分工、多重繼承下的 vptr 複雜度、thunk 調整器機制。

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