以前虽然考虑过这个问题,但是试了下以后就以为虚函数表在内存的代码区里,后来还被问到虚函数表在内存中的哪里,回答不同编译器对虚函数的处理是不一样的,今天仔细的测了测。
当然以下的测试是在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)。
总结:虚函数表由于一旦产生就具有不变性,所以编译器就会经量把它放到稳定(或者说是只读)的内存区。