以前雖然考慮過這個問題,但是試了下以后就以為虛函數表在內存的代碼區里,后來還被問到虛函數表在內存中的哪里,回答不同編譯器對虛函數的處理是不一樣的,今天仔細的測了測。
當然以下的測試是在win7的VS2010下。有錯誤歡迎批評指出,謝謝。
測試代碼
#include <iostream> using namespace std; class Base1 { public: virtual void f() { cout << "Base1::f" << endl; } virtual void g() { cout << "Base1::g" << endl; } virtual void h() { cout << "Base1::h" << endl; } }; class Base2 { public: virtual void f() { cout << "Base2::f" << endl; } virtual void g() { cout << "Base2::g" << endl; } virtual void h() { cout << "Base2::h" << endl; } }; class Base3 { public: virtual void f() { cout << "Base3::f" << endl; } virtual void g() { cout << "Base3::g" << endl; } virtual void h() { cout << "Base3::h" << endl; } }; class Derive : public Base1, public Base2, public Base3 { public: virtual void f() { cout << "Derive::f" << endl; } virtual void g1() { cout << "Derive::g1" << endl; } }; typedef void(*Fun)(void); int main() { Base1* d=new Derive; return 0; }
觀察其中一個虛函數的指針指向的位置:
注意下面那個字符串,如果你沒有看到字符串的話一定不知道這是在內存的哪個區,看到字符串就知道,這是在內存的常量區,也就是虛函數被放在這里,被放在這里也還是比較容易理解的,因為,虛函數表是不需要改變的,放在常量區是比較保險的做法。
后再在網查了查,知道虛函數表vtable在Linux/Unix中存放在可執行文件的只讀數據段中(rodata)。
總結:虛函數表由於一旦產生就具有不變性,所以編譯器就會經量把它放到穩定(或者說是只讀)的內存區。