码迷,mamicode.com
首页 > 其他好文 > 详细

使用虚函数表指针来调用虚函数遇到的问题

时间:2020-04-20 13:39:17      阅读:61      评论:0      收藏:0      [点我收藏+]

标签:ret   理解   返回值   写代码   vptr   转变   大小   遇到   static   

使用虚函数表指针来调用虚函数遇到的问题

定义一个Father类,代码如下:

class Father {
public:
virtual void func1() {cout << "Father::func1" << endl;}
virtual void func2() { cout << "Father::func2" << endl; }
virtual void func3() { cout << "Father::func3" << endl; }
void func4() { cout << "非虚函数:Father::func4" << endl; }
public:
int x = 200;
int y = 300;
static int z;
};

typedef void (*func_t)(void);

int main(void){

Father father;


cout << "对象father地址:" <<(int)&father << endl;
int* vptr = (int*)*(int*)(&father);//函数指针,int*类型
cout << "vptr:" << vptr << endl;

//((void (*)(void))vptr)(); wrong

((void(*)(void))*(vptr))();

((func_t) * (vptr + 0))();
((func_t) * (vptr + 1))();
((func_t) * (vptr + 2))();

? return 0;

}

解释:对father对象取地址得到一个地址,因为地址里面存储的值是一个虚函数表指针,而函数指针占四个字节,因此将地址转为(int *)类型以告诉编译器内存大小,再解引得到虚函数表指针,最后再转为(int *)类型,得到了虚函数表的指针,此时为(int *)类型,最后通过这个int *类型的指针来调用虚函数,如何调用?先得转变指针的类型,因为指针指向的虚函数的返回值是空。

因此定义一个类型

typedef void(*func_t)(void);

然后写代码((func_t) * (vptr + 0))();即可调用虚函数,即先解引虚函数表的指针,得到虚函数的指针,这里注意:区别虚函数表指针与虚函数指针!不然会发生错误,这里需要经过两次解引用!第一次是对&father解引得到虚函数表指针,然后是对虚函数表指针解引得到虚函数指针。

所以不用自定义类型来调用虚函数也很明白了,代码应该这样子写
:((void( *) (void) )) *(vptr))();
千万不要像我之前那样调用((void( *) (void) ))(vptr))(); 将虚函数表指针与虚函数指针混为一谈,闹了笑话。

主要还是理解虚函数表指针这个概念吧!

使用虚函数表指针来调用虚函数遇到的问题

标签:ret   理解   返回值   写代码   vptr   转变   大小   遇到   static   

原文地址:https://www.cnblogs.com/Ybossy/p/12737069.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!