1. 程式人生 > >虛擬函式表存放在哪裡

虛擬函式表存放在哪裡

1.虛擬函式表是全域性共享的元素,即全域性僅有一個.

2.虛擬函式表類似一個數組,類物件中儲存vptr指標,指向虛擬函式表.即虛擬函式表不是函式,不是程式程式碼,不肯能儲存在程式碼段.

3.虛擬函式表儲存虛擬函式的地址,即虛擬函式表的元素是指向類成員函式的指標,而類中虛擬函式的個數在編譯時期可以確定,即虛擬函式表的大小可以確定,即大小是在編譯時期確定的,不必動態分配記憶體空間儲存虛擬函式表,所以不再堆中.

根據以上特徵,虛擬函式表類似於類中靜態成員變數.靜態成員變數也是全域性共享,大小確定.

所以我推測虛擬函式表和靜態成員變數一樣,存放在全域性資料區.

c/c++程式所佔用的記憶體一共分為五種: 棧區,堆區,程式程式碼區,全域性資料區(靜態區),文字常量區.

顯而易見,虛擬函式表存放在全域性資料區.

幾個值得注意的問題

  1、虛擬函式表是class specific的,也就是針對一個類來說的,這裡有點像一個類裡面的staic成員變數,即它是屬於一個類所有物件的,不是屬於某一個物件特有的,是一個類所有物件共有的。  

2、虛擬函式表是編譯器來選擇實現的,編譯器的種類不同,可能實現方式不一樣,就像前面我們說的vptr在一個物件的最前面,但是也有其他實現方式,不過目前gcc 和微軟的編譯器都是將vptr放在物件記憶體佈局的最前面。  

3、雖然我們知道vptr指向虛擬函式表,那麼虛擬函式表具體存放在記憶體哪個位置呢,雖然這裡我們已經可以得到虛擬函式表的地址。實際上虛擬函式指標是在建構函式執行時初始化的,而虛擬函式表是存放在可執行檔案中的。下面的一篇部落格測試了微軟的編譯器將虛擬函式表存放在了目標檔案或者可執行檔案的常量段中,http://blog.csdn.net/vicness/article/details/3962767,不過我在gcc下的彙編檔案中沒有找到vtbl的具體存放位置,主要是對可執行檔案的裝載和執行原理還沒有深刻的理解,相信不久有了這些知識之後會很輕鬆的找到虛擬函式表到底存放在目標檔案的哪一個段中。

4、經過測試,在gcc編譯器的實現中虛擬函式表vtable存放在可執行檔案的只讀資料段.rodata中。 

虛擬函式表vtable在Linux/Unix中存放在可執行檔案的只讀資料段中(rodata),這與微軟的編譯器將虛擬函式表存放在常量段存在一些差別。 

參考文獻:

1. http://blog.csdn.net/vicness/article/details/3962767

2. 深度探索c++物件模型