问两个有关虚指针和虚表的问题
1 由带virtual关键字的类实例化出来的对象,是不是每一个virtual关键字对应一个虚指针,还是一个对象有一个虚指针?假设有五个虚函数吧。
2 虚表是象static 一样一个类共有的,还是每实例化一个对象都会生成一张虚表呢。也就是虚表在内存中有几份拷贝,是存放在堆中还是栈中的?
问题点数:20、回复次数:4Top
1 楼sjjf(水晶剑锋)回复于 2006-03-04 00:34:03 得分 10
===========================================
1 由带virtual关键字的类实例化出来的对象,是不是每一个virtual关键字对应一个虚指针,还是一个对象有一个虚指针?假设有五个虚函数吧。
2 虚表是象static 一样一个类共有的,还是每实例化一个对象都会生成一张虚表呢。也就是虚表在内存中有几份拷贝,是存放在堆中还是栈中的?
===========================================
1.每一个带有virtual关键字的类,包括他的子类,编译器都会为其建立一张虚函数表。
每一个类一张虚函数表,该类里的所有的虚函数都会放到这个虚函数表中。
这个虚函数表是放在内存中的某处,所有的该类的实例都共用它。至于它存放位置,肯定是在堆里,但在堆里面的具体那个位置,我也不太清楚,等我弄清楚了我在告诉你,
类的实例化过程实际上是先分配内存(可能在堆里也可能在栈里分配),
如果没有虚函数的类,它的实例的内存大小和他的成员一致,
如果有虚函数的话,编译器会编译时给类的内存区域加大
一个指针的内存空间(32位下4个字节),类中各个成员一次往后排,
如果有构造函数的话,就会调用构造函数进行初始化。
对于带虚函数的类,必须有构造函数,如果没有的话,编译器会自动产生一个默认的。
构造函数工作时会把该类虚函数表的地址填充入类实例起始地址(也就是那个指针空间)。
之后是调用构造函数进行初始化工作。
验证代码如下:
#include "stdafx.h"
class parentA
{
public :
int iA;
virtual void fa();
};
class A:public parentA
{
public :
int i1;
int i2;
void fa();
};
void parentA::fa()
{
printf("\n parentA iA =[%d] \n",this->iA);
}
void A::fa()
{
printf("\n i1 =[%d],i2=[%d] \n",this->i1,this->i2);
}
void foo1()
{
A a;
a.i1 = 1;
a.i2 = 2;
a.fa();
}
void foo2()
{
A a;
parentA pa;
printf("A老爸的虚函数表的地址:[%d] ",*((unsigned int *)(&pa)));
printf("A虚函数表的地址:[%d] ",*((unsigned int *)(&a)));
int t1[4] ;
t1[1] = 3;
t1[2] = 4;
t1[3] = 5;
((A *)&t1)->A::A();
((parentA *)&t1)->fa();
printf("模拟-- A的虚函数表的地址:[%d]",t1[0]);
((parentA *)&t1)->parentA::parentA();
((parentA *)&t1)->fa();
printf("模拟-- A老爸的虚函数表的地址:[%d]",t1[0]);
//获取虚函数表的地址还可以实例化一个有虚函数的类,然后将这个类的首地质拷贝出来。
}
int main(int argc, char* argv[])
{
foo1();
foo2();
return 0;
}
具体的分析见
http://community.csdn.net/Expert/topic/4532/4532843.xml?temp=.547619
Top
2 楼cunsh(村少)回复于 2006-03-04 01:00:21 得分 5
1
一个对象只要一个虚指针就行了.
2
一个类只要一个虚表就行了.Top
3 楼wzjall(风)回复于 2006-03-04 01:06:52 得分 5
这个有两种情况:
1.虚函数在你设计的类中占的比例比较大,且重写率不是很高时,象vc中的类.
vc采用的就是一个虚表.(vc中是通过设计一些巧妙的宏来访问基类的函数的)
这种方法节省内存,但效率不是很高,因为它需要通过指针往上一级级的查找
2.一1.相反,这种情况采用的是内存直接定位,效率高,但占内存(不过没关系,因为虚函数在你设计的类中占的比例比较小),这种编译器的实例给忘了.
这是我在一本杂志上看到的说法,理解不当之出,请间量Top
4 楼yxg80(林夕昱)回复于 2006-03-04 21:07:48 得分 0
以前不知道Vtable什么的,今天就好好学习了!Top




