c++虚函数问题,大神请进 20

为啥打印*p和p的值是一样的?为啥段错误?... 为啥打印*p和p的值是一样的?为啥段错误? 展开
 我来答
heptnaol
2018-09-30 · TA获得超过7261个赞
知道大有可为答主
回答量:7120
采纳率:78%
帮助的人:1811万
展开全部

1,对函数指针来说,指针值是函数地址,取*还是函数地址,所以相等看起来是没啥问题的。

2,不能这么调用,成员函数是隐含带有this参数的,和普通函数不一样。

对象内存的第一个指针是vtable(如果有),vtable是一个void **类型的指针,每一项都是一个函数指针,所以你的代码也是没法正确运行的。

以下是我的测试代码,VS2015可正确运行

不过这么调用看似成功,还有问题,访问成员变量就会有问题。

原因是show的函数地址虽然正确找到,但是函数的具体实现却不是简单的把第一个参数当作this,具体可查看反汇编指令。

查了一下,VS2015 this是使用ecx寄存器传递的

int main()
{
     Dad d;
         //把d看成void **指针的数组即可
         void **vtbl = reinterpret_cast<void ***>(&d)[0]; 
         void *ptrShow = vtbl[0]; //show的指针是vtable的第0个元素
         void(*pFunc) (); //声明一个普通函数指针
         pFunc = reinterpret_cast<void(*) ()>(ptrShow);
         //不能访问成员变量,因没有this指针
         pFunc();  //调用方式
         return 0;
}
百度网友4ebdd63
2018-09-29 · 超过53用户采纳过TA的回答
知道小有建树答主
回答量:123
采纳率:76%
帮助的人:40.4万
展开全部
你给转换的不是虚函数的地址而是类D的地址,调用当然出错了
追答
我很好奇你这样做是为了什么?
追问
对象d的第一个成员应该是vptr指针,指向vtable表,64位系统下把d的首地址强转为long*再取*,那就相当于取到了vtable表的首地址(vtable表应该就是一个函数指针数组啊),只不过是以long类型去解释函数指针类型,但long类型和指针类型都是8字节,不丢失数据,把vtable表的首地址强转为函数指针类型,那对该指针取星就应该得到了函数入口地址,后面加上()为啥不能调用呢?
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式