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

C++ 對象佈局與多態實現:帶虛函數的類佈局詳解

     編輯:關於C++

單一虛函數類的佈局

struct C040 { virtual void foo() {} };

對象大小 4 字節(32 位),僅含 vptr 指向類級虛表。多個對象共享同一虛表,虛表條目指向實際函數代碼(通常經一條跳轉指令)。

繼承與虛函數覆寫

struct C050 : C040 {}; // 未覆寫,共享虛表條目
struct C071 : C043 { virtual void foo1() {} } // 覆寫 foo1,虛表首項變更

驗證:基類與派生類虛表首項地址不同(覆寫),第二項相同(未覆寫)。

多重繼承:多個 vptr

struct C041 { virtual void foo(); char c_; };
struct C042 { virtual void foo2(); char c_; };
struct C051 : public C041, public C042 {};

C051 大小 10 字節:[vptr1][C041::c_][vptr2][C042::c_]。兩個 vptr 分別指向各自的虛表,虛表條目繼承自對應基類。

為何不合併虛表?為了方便動態轉換時直接調整指針指向對應子對象起始位置,統一調用機制。

派生類新增虛函數放入首個虛表

struct C082 : public C041, public C042 {
virtual void foo();
virtual void foo2();
virtual void foo3(); // 新增
char c_;
};

實驗證明:foo3 的地址出現在第一個虛表的繼承條目之後(索引 1),第二個虛表大小不變。調用 c082.foo3() 的匯編 call 0041D32F 對應第一虛表第二項。

總結

  • 含虛函數類對象首部放 vptr,指向類級虛表(指針數組)。
  • 單繼承共享虛表,覆寫替換對應條目。
  • 多重繼承每個含虛函數的基類對應一個 vptr,派生類新增虛函數加入首個虛表尾部。
  • 此佈局設計服務於動態綁定與動態轉換的高效實現。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved