1. 虛表與“虛函數表”
在“C/C++雜記:虛函數的實現的基本原理”一文中曾提到“虛函數表”的概念,只是為了便於理解,事實是:虛函數表並不真的獨立存在,它只是虛表(virtual table)中的一部分內容。例:
從圖中可已看出,虛表除了包含虛函數指針,還包含其它一些信息(如:RTTI信息、偏移值等)。
順便介紹一下gcc的-fdump-class-hierarchy選項,它可以用於輸出C++程序的虛表結構(在當前目錄下生成一個.class文件),例:
2. 虛表結構
一個虛表包含以下幾個部分:
其中:
- 橙色線框中的內容僅限於虛擬繼承的情形(若無虛擬繼承,則無此內容),虛擬繼承的討論已超過了本文的范圍,暫且忽略。
- “offset to top”是指到對象起始地址的偏移值,只有多重繼承的情形才有可能不為0,單繼承或無繼承的情形都為0。
- “RTTI information”是一個對象指針,它用於唯一地標識該類型。(注:本系列博文后續會有詳細討論。)
- “virtual function pointers”也就是我們之前理解的虛函數表,其中存放着虛函數指針列表。
前一節的示例是單繼承的示例,下面列出了一個多繼承的示例:
從中可以看到:D的虛表中包含兩個虛表結構,第一個也稱之為“主虛表”(primary virtual table),另一個虛表又稱之為“次虛表”(secondary virtual table)。
簡單地概括一下:一個含有虛函數(無論是其本身的,還是繼承而來的)的類,可以有一個主虛表和多個次虛表,主虛表和次虛表構成一個虛表組(virtual table group)。