您好,登录后才能下订单哦!
这篇文章主要讲解了“C++的函数指针用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++的函数指针用法”吧!
看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++的函数指针用法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。