(int*)*(int*)(&b) 是什么意思

notebook2001a 2009-09-04 03:27:47
#include <stdio.h>
#include <iostream>
using namespace std;
class Base {
public:
virtual void f()
{
cout << "Base::f" << endl;
}virtual void g()
{
cout << "Base::g" << endl;
}
virtual void h()
{
cout << "Base::h" << endl;
}
};


int main()
{

typedef void(*Fun)(void);
Base b;
Fun pFun = NULL;
cout << "虚函数表地址:" << &b<< endl;
cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;
pFun = (Fun)*((int*)*(int*)(&b));
pFun();

return 0;

}

谁能解释一下这段代码是什么意思 cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;
...全文
4498 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
A5121612886 2011-05-15
  • 打赏
  • 举报
回复
六楼的说的太好了!
wjg945 2011-02-25
  • 打赏
  • 举报
回复
有点晕~~
ColdMooon 2010-08-08
  • 打赏
  • 举报
回复
(int*)*(int*)(&b)就等于(int*&)b
ForestDB 2010-08-08
  • 打赏
  • 举报
回复 2
对b取地址(&b)
将其当int*看/cast成int*((int*)(&b))
对其解引用(*(int*)(&b))
解引用的结果将其当int*看((int*)*(int*)(&b))

至于它是不是虚函数表第一个函数的地址或者为什么是,需要查阅Inside the C++ Object Model。
illuminati 2010-08-07
  • 打赏
  • 举报
回复
学习了
Wade_Song 2010-08-07
  • 打赏
  • 举报
回复
学习了。。我很怕的东东。。
wangbinykit 2010-05-18
  • 打赏
  • 举报
回复
标记一下,慢慢理解
  • 打赏
  • 举报
回复 2
(int*)*(int*)(&b)

把B的地址强制转换成INT *型指针。。。

再取出INT *指向空间的内容再强制转换成INT *
赵4老师 2010-05-18
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
Sunday 2010-05-18
  • 打赏
  • 举报
回复
reddeer608 2010-05-18
  • 打赏
  • 举报
回复
学习了。真的很不错。
knate 2009-09-05
  • 打赏
  • 举报
回复
你试一下这个:

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

hoomey 2009-09-05
  • 打赏
  • 举报
回复
学习
diablox0147 2009-09-05
  • 打赏
  • 举报
回复
我同意hairetz的。。感觉这个说的有点错误,
&b应该是类的首地址。
(int*)*(int*)(&b)); 这个应该才是虚函数表的地址
(int*)*((int*)*(int*)(&b));//这个应该才是第一个虚函数的地址...
JaneThink 2009-09-04
  • 打赏
  • 举报
回复
感觉是理解了,不是说虚函数表中的函数都是顺序存放的。这样的话。第二个虚函数数的地址是不是:

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


如果是的话为什么调用这个函数会出错呢?
  • 打赏
  • 举报
回复
反正我认为
(int*)*((int*)*(int*)(&b)); 才是虚表第一个虚函数的地址。

(int *)table_ptr=(int *) *(int*)(&b); //获取b对象的第一个int数据,值是虚表的地址

(int*)*table_ptr //这个地址再取值,就是虚表第一个函数指针,转成(int *)

不难理解吧
whg01 2009-09-04
  • 打赏
  • 举报
回复 1
如果有虚函数的话,类的第一个元素是一个指针p,该指针指向虚函数表。虚函数表中每个元素是函数指针。
(&b)
取得第一个元素的地址,即&p。
(int*)(&b)
把这个地址的类型转换为(int*)
*(int*)(&b)
对这个地址进行解引用,得到p的值q,p是指向虚函数表的指针,所以p的值是虚函数表中第一个元素。
(int*)*(int*)(&b)
将q的类型转为(int*)
Baesky 2009-09-04
  • 打赏
  • 举报
回复 1
(int*)*(int*)(&b)

&b : 一个指针
int* : 一个指向整型的指针
*(int*) : 一个指向整型的指针的指针
(int*) :一个指向整型的指针

一个指针他的类型是一个指向整型类型的指针的指针,而这个指针的类型是一个指向指向整型的指针




yshuise 2009-09-04
  • 打赏
  • 举报
回复 3
pFun = (Fun)*((int*)*(int*)(&b));
上面这种写法,是假定vptr放在对象模型的开头,因为对于一个类如果有成员变量,那么
这个虚拟指针(vptr)可以放在末尾,或是其它的地方,标准并没有对此有规定,因此这种说法不一定正确。
但是,
我们这儿纯属讨论使用,假vptr定放在对象模型的开头。
这样&b,这就是vptr的地址(放在开头),然后这个地址转换成(int*),再对它进行解引用*,
也就是*(int*)(&b),这个解引用是什么呢?
我们知道vptr指向vtable,而vtable是存放虚函数的地址。对vptr的解引用(*),实际上
就是访问vtable,(vtable可以存放很多函数的地址,为求简单,现在我们只考虑一个),
然后,我们再把这个vtable指针转化成(int*),然后再解引用,前面我们已经说过,vtable存放的是函数的指针,当对vtable进行解引用的时候,实际上就是指向这个函数了。
icansaymyabc 2009-09-04
  • 打赏
  • 举报
回复
结帖率:37.93%
加载更多回复(4)

64,660

社区成员

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

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