一直对虚函数不太理解,今天写了个小程序玩玩,也算有点心得.
class base
{
int i;
public:
base(int I=0):i(I){}
virtual int sum() const
{
return i;
}
void printf_i_address()
{
printf("i address is :%x/n", &i);
}
};
class derived:public base
{
int j;
public:
derived(int I=0,int J=0):base(I),j(J) {}
int sum() const {return base::sum()+j;}
virtual int total() const {return 300;}
void printf_j_address()
{
printf("j address is %x/n",&j);
}
};
void call(base &b)
{
printf("%d/n",b.sum());
}
主程序
base b(100);
derived d(100,200);
call(b);
call(d);
printf("base size:%d/n",sizeof(b) );
printf("derived size: %d/n", sizeof(d) );
printf("base sum address: %x/n",&base::sum);
printf("derived sum address: %x/n",&derived::sum);
printf("derived total address: %x/n",&derived::total);
int* p=(int *)&d;
printf("derived address = %x/n", p);
printf("i=%x /n",*(int*)(p+1) );
d.printf_i_address();
printf("j=%x/n", *(int*)(p+2) );
d.printf_j_address();
int vptr=*p;
printf("vptr address: %x/n",vptr);
printf("vptr1 address: %x/n",*(int*)vptr);
printf("vptr2 address: %x/n",*(int*)(vptr+4) );
结果输出有点出人意料
&base::sum == &derived::sum (在我的机器上都是401130,而且跟*(int*)vptr 不等)
不是因该相等的吗?
没办法,从汇编看
401130是啥
.text:00401130 loc_401130: ; DATA XREF: _wmain+6Bo
.text:00401130 ; _wmain+77o
.text:00401130 mov eax, [ecx]
.text:00401132 jmp dword ptr [eax]
明白了,这就是虚函数, 直接跳转到vptr 表中的函数,也就是*(int*)vptr .
从实现原理看,就是变 不变代码到动态代码.(不知道是不是说的清楚)