from: herec++
1.虛函數表是全局共享的元素,即全局僅有一個.數組
2.虛函數表相似一個數組,類對象中存儲vptr指針,指向虛函數表.即虛函數表不是函數,不是程序代碼,不願能存儲在代碼段.函數
3.虛函數表存儲虛函數的地址,即虛函數表的元素是指向類成員函數的指針,而類中虛函數的個數在編譯時期能夠肯定,即虛函數表的大小能夠肯定,即大小是在編譯時期肯定的,沒必要動態分配內存空間存儲虛函數表,因此再也不堆中.佈局
根據以上特徵,虛函數表相似於類中靜態成員變量.靜態成員變量也是全局共享,大小肯定.測試
因此我推測虛函數表和靜態成員變量同樣,存放在全局數據區.spa
c/c++程序所佔用的內存一共分爲五種:.net
棧區,堆區,程序代碼區,全局數據區(靜態區),文字常量區.指針
顯而易見,虛函數表存放在全局數據區.對象
幾個值得注意的問題blog
- 虛函數表是class specific的,也就是針對一個類來講的,這裏有點像一個類裏面的staic成員變量,即它是屬於一個類全部對象的,不是屬於某一個對象特有的,是一個類全部對象共有的。
- 虛函數表是編譯器來選擇實現的,編譯器的種類不一樣,可能實現方式不同,就像前面咱們說的vptr在一個對象的最前面,可是也有其餘實現方式,不過目前gcc 和微軟的編譯器都是將vptr放在對象內存佈局的最前面。
- 雖然咱們知道vptr指向虛函數表,那麼虛函數表具體存放在內存哪一個位置呢,雖然這裏咱們已經能夠獲得虛函數表的地址。實際上虛函數指針是在構造函數執行時初始化的,而虛函數表是存放在可執行文件中的。下面的一篇博客測試了微軟的編譯器將虛函數表存放在了目標文件或者可執行文件的常量段中,http://blog.csdn.net/vicness/article/details/3962767,不過我在gcc下的彙編文件中沒有找到vtbl的具體存放位置,主要是對可執行文件的裝載和運行原理尚未深入的理解,相信不久有了這些知識以後會很輕鬆的找到虛函數表到底存放在目標文件的哪個段中。
- 通過測試,在gcc編譯器的實現中虛函數表vtable存放在可執行文件的只讀數據段.rodata中。
虛函數表vtable在Linux/Unix中存放在可執行文件的只讀數據段中(rodata),這與微軟的編譯器將虛函數表存放在常量段存在一些差異。