from: here
1.虚函数表是全局共享的元素,即全局仅有一个.
2.虚函数表类似一个数组,类对象中存储vptr指针,指向虚函数表.即虚函数表不是函数,不是程序代码,不肯能存储在代码段.
3.虚函数表存储虚函数的地址,即虚函数表的元素是指向类成员函数的指针,而类中虚函数的个数在编译时期可以确定,即虚函数表的大小可以确定,即大小是在编译时期确定的,不必动态分配内存空间存储虚函数表,所以不再堆中.
根据以上特征,虚函数表类似于类中静态成员变量.静态成员变量也是全局共享,大小确定.
所以我推测虚函数表和静态成员变量一样,存放在全局数据区.
c/c++程序所占用的内存一共分为五种:
栈区,堆区,程序代码区,全局数据区(静态区),文字常量区.
显而易见,虚函数表存放在全局数据区.
几个值得注意的问题
- 虚函数表是class specific的,也就是针对一个类来说的,这里有点像一个类里面的staic成员变量,即它是属于一个类所有对象的,不是属于某一个对象特有的,是一个类所有对象共有的。
- 虚函数表是编译器来选择实现的,编译器的种类不同,可能实现方式不一样,就像前面我们说的vptr在一个对象的最前面,但是也有其他实现方式,不过目前gcc 和微软的编译器都是将vptr放在对象内存布局的最前面。
- 虽然我们知道vptr指向虚函数表,那么虚函数表具体存放在内存哪个位置呢,虽然这里我们已经可以得到虚函数表的地址。实际上虚函数指针是在构造函数执行时初始化的,而虚函数表是存放在可执行文件中的。下面的一篇博客测试了微软的编译器将虚函数表存放在了目标文件或者可执行文件的常量段中,http://blog.csdn.net/vicness/article/details/3962767,不过我在gcc下的汇编文件中没有找到vtbl的具体存放位置,主要是对可执行文件的装载和运行原理还没有深刻的理解,相信不久有了这些知识之后会很轻松的找到虚函数表到底存放在目标文件的哪一个段中。
- 经过测试,在gcc编译器的实现中虚函数表vtable存放在可执行文件的只读数据段.rodata中。
虚函数表vtable在Linux/Unix中存放在可执行文件的只读数据段中(rodata),这与微软的编译器将虚函数表存放在常量段存在一些差别。
参考文献:
1. http://blog.csdn.net/vicness/article/details/3962767
2. 深度探索c++对象模型
时间: 2024-12-12 18:56:36