虚函数表的问题。。。

jianpanlanyue 2008-10-19 07:40:01
#include <iostream.h>

typedef void(*Fun)(void);

class Base {

public:

virtual void f() { cout << "Base::f" << endl; }

virtual void g() { cout << "Base::g" << endl; }

virtual void h() { cout << "Base::h" << endl; }

};


void main()
{
Base b;

Fun pFun = NULL;

cout << "虚函数表地址:" << (int *)(&b) << endl;

cout << "虚函数表 — 第一个函数地址:" << (int*)(*(int *)(&b)) << endl;

// Invoke the first virtual function

pFun = (Fun)*((int*)*(int*)(&b));

pFun();

}

输出结果两个地址不一样,为什么?虚函数表中第一个函数的地址不就是虚函数表的首地址么?
还有,我不是怎么很懂(int*)(*(int *)(&b)这句话。实力的地址用&取出后干吗要加一个(int*)?

...全文
125 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
jianpanlanyue 2008-10-19
  • 打赏
  • 举报
回复
谢。。。。
帅得不敢出门 2008-10-19
  • 打赏
  • 举报
回复
虚函数表中放着虚函数地址
要取虚函数地址必须对虚函数表地址进行解引用才能得到虚函数地址
这两者地址怎么可能是一样的????
chlaws 2008-10-19
  • 打赏
  • 举报
回复
还占一个虚表指针,虚函数是通过虚表指针来间接调用的...
机智的呆呆 2008-10-19
  • 打赏
  • 举报
回复
所以可近似的认为虚表指针**p指向的是一个二维数组,

int a[10][1];
p= (int *)(&b)---------->a
*p= *(int*)(&b)------------a[0]
**p= (int*)(*(int *)(&b)--->a[0][0]//函数的地址值

数组类型可能不合理~~~~
不过解析的道理差不多
beiyang9 2008-10-19
  • 打赏
  • 举报
回复
对这句而言:(int *)(&b),&b表示类实例在进程中的起始地址,然后将该地址转化为int指针形。
在特定的情况下,比如你例子中,就是假设了,vptr(虚表指针)在类实例头部,该指针指向虚表地址,也就是说该地址里存了另一个地址。
对这句而言: (int*)(*(int *)(&b)),其中,(*(int *)(&b))表示取出vptr指向地址的内容。而该内容其实还是个地址,所以(int*)转化为指针,这样就指向虚表在进程中的位置了,下面就是平常的函数指针操作了
帅得不敢出门 2008-10-19
  • 打赏
  • 举报
回复
对象有一个vptr->虚函数表 然后虚函数表中存放虚函数地址

机智的呆呆 2008-10-19
  • 打赏
  • 举报
回复
Base b;
系统为b对象分配足够的内存,其中b标示着这块内存,&b表示这块内存的起始地址,
一般来说虚表指针放在对象的起始处,所以(int *)(&b)这句话的作用是,从&b地址值开始,往下涵盖四个内存单位(指针变量)也就是四个字节,取出其中的数据组成一个值,而这个值被解析成 某int指针变量的值,而这个值就是虚表指针变量的值,也就是说内存起始的四个字节内存是分配给虚表指针的~~~
(int *)(&b)这个值指向了续表的起始地址,加一个*进行解引用时,因为前面说了它的类型,他会从(int *)(&b)地址开始往下涵盖四个字节(int形)的内存,把其中数据取出解析成一个int变量的值,而这个值是就是虚表的第一个元素的值,
然后对这个值,同上面一样在强制解析一次就是虚表第一个元素指向的内存的值,也就是函数的地址值,
最后Fun转换下,用fun方式解析这个值~~~

所以有虚函数的情况下,编译器安插在对象起始的四个字节,是为一个指向指针的指针变量分配的,他所指向的指针变量的是一个函数指针,
指针这些很容易就可以同过 数组越界 修改编译器所生成的这个指针的值~~~
jianpanlanyue 2008-10-19
  • 打赏
  • 举报
回复
虚函数表没有很清楚。。。

65,206

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧