189 8069 5689

C++的函数指针用法

这篇文章主要讲解了“C++的函数指针用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++的函数指针用法”吧!

创新互联公司专注于企业成都营销网站建设、网站重做改版、莆田网站定制设计、自适应品牌网站建设、HTML5商城系统网站开发、集团公司官网建设、外贸营销网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为莆田等各大城市提供网站开发制作服务。

看C++代码时看到了一段很新奇的用法, 回来剖析了一下, 感觉虽然原理很简单还是值得记录一下的。

代码大概是这个样子的:

class test {
public:
       void a1(){printf("test::a1\n");};
}

int main()
{
       test *t = new test();
       void (test::*a)(void);
       a = &test::a1;
       (t->*a)();
}

以前在C++中用函数指针时,从来都反射性的去用静态成员函数, 却从来都没想到原来普通的成员函数也是可以使用函数指针的。

仔细分析一下, 原理也早就知道。 无非就是this指针的事。

使用test对象的指针去调用某函数与普通的C函数指针惟一的区别就是, 会将test对象的指针作为this指针通过ecx寄存器来传入, 那么所有的C++类成员函数在本质上也是通过ecx的值来访问他们的成员变量。


在不反汇编的情况下, 为了更清晰的验证一下上述结论, 加入了如下代码:

void (*b)(void);
b = (void (*)(void))&test::a1;
b();

最后可以发现函数依然可以运行。

当然这里其实有点取巧,因为test::a1函数并没有访问类的成员变量, 所以我们可以将此成员函数直接作为普通的函数来调用。


如果test::a1函数访问成员变量的话, 由于C函数调用时并没有传入this指针, 那么test::a1函数必将会由于随机的ecx值而导致崩溃。

但是这段代码已经足够证明,&test::a1给出的是函数的绝对地址与普通的C函数的地址并无两样,那么调用b()和(t->*a)()的区别其实就在于是否传入了this指针。

如果再有点hack精神, 其实可以去将test::a1函数更改为访问成员变量, 然后在调用C函数前, 可以手动内嵌asm代码来将ecx值强制改为t的指针值, 如果效果一样, 那么即可完全证明上述结论。

感谢各位的阅读,以上就是“C++的函数指针用法”的内容了,经过本文的学习后,相信大家对C++的函数指针用法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!


网站名称:C++的函数指针用法
当前链接:http://cdxtjz.cn/article/iggsjh.html

其他资讯