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

C++ 物件模型核心筆記:從佈局到虛函數表

     編輯:關於C++

前言

《C++ 物件模型》一書深入剖析 C++ 底層實作機制。本文整理核心知識點,涵蓋物件佈局、虛函數表、繼承模型、建構函式語意等,助你透視 C++ 「引擎蓋下」的運作邏輯。

一、C++ 物件模型包含什麼?

  • 語言直接支援的 OO 特性(類別、繼承、多型)
  • 底層實作機制(記憶體佈局、虛表、指標調整等)

二、資料成員與成員函式的儲存規則

類型儲存位置
non-static 資料成員類別物件內部
static 資料成員所有物件之外(data segment),僅一份實體
static / non-static 成員函式類別物件之外(代碼段)
virtual 函式不佔物件空間,透過 vptr/vtable 機制

三、虛函數機制:vptr 與 vtable

  1. 每個含虛函數的類別產生一張虛函數表(vtable),表項為函數指標。
  2. 每個類別物件隱含一個指標(vptr),指向其類別的 vtable。
  3. 呼叫虛函數時:obj->vptr[vtable_index] 間接跳轉,實現動態繫結。

四、繼承與虛擬繼承

單一繼承

衍生類別物件包含基底類別子物件,vptr 指向衍生類別的 vtable(覆寫函數已更新)。

多重繼承

物件包含多個基底子物件,每個基底有自己的 vptr,衍生類別可能有多個 vptr。

虛擬繼承

無論在繼承鏈中出現多少次,虛擬基底類別在衍生物件中永遠只有一個實體。編譯器透過額外指標或偏移量實現共享,增加存取開銷但解決菱形繼承問題。

五、關鍵字 struct vs class

  • struct:預設 public 繼承/成員,體現「資料聚合」概念。
  • class:預設 private,體現 ADT(抽象資料類型)封裝概念。
  • 底層實作無差異,純粹語意與預設可見性不同。

六、建構函式與拷貝語意

  • 編譯器合成的預設建構函式僅初始化基底與類別成員,不初始化 non-static 資料成員(除非它們有預設建構函式)。
  • 成員初始化順序遵循類別中宣告順序,而非初始化列表順序。
  • 預設拷貝建構函式執行 bitwise copy(位元逐位拷貝),針對指標成員易導致雙重釋放錯誤,需自訂深層拷貝。

七、空類別大小與對齊

  • 空類別大小至少 1 byte,確保每個物件擁有唯一位址。
  • 類別大小受三因素影響:語言額外負擔(vptr)、編譯器優化(空基底優化 EBO)、記憶體對齊需求(如 32 位系統 4 byte 對齊)。

八、指標本質

指標大小固定,其類型僅告知編譯器如何解讀所指記憶體(解引用大小、算術運算步長)。指標轉型不改變位址值,只改變編譯器對該記憶體的「解讀方式」。

九、物件切割

以衍生類別物件初始化基底類別物件(或傳值給基底參數)時,衍生部分被「切掉」,僅保留基底子物件。避免方式:使用指標/參考傳遞、多型設計。

總結

理解物件模型能幫你:預估物件大小、避免切割陷阱、優化虛函數呼叫、正確管理資源生命週期。C++ 高效能的代價是程式設計師必須理解其底層契約。

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