向普通函数传递类成员函数指针的问题

举报
ShaderJoy 发表于 2021/11/18 23:56:53 2021/11/18
【摘要】 成员函数func3=>成员函数func2: 将一个类成员函数的函数指针传递给另一个成员函数是比较简单的,只要定义一个函数指针就可以轻松实现。示例如下: #include <iostream>using namespace std;class test{public: typedef void (test::*p...

成员函数func3=>成员函数func2:

将一个类成员函数的函数指针传递给另一个成员函数是比较简单的,只要定义一个函数指针就可以轻松实现。示例如下:


  
  1. #include <iostream>
  2. using namespace std;
  3. class test
  4. {
  5. public:
  6. typedef void (test::*pFUN)();
  7. void func1()
  8. {
  9. func2(&test::func3); //把func3的指针传递给func2
  10. }
  11. void func2(pFUN pfun)
  12. {
  13. (this->*pfun)();
  14. }
  15. void func3()
  16. {
  17. cout<<"test func3."<<endl;
  18. }
  19. };
  20. main()
  21. {
  22. void (test::*pfun)() = &test::func3; //把func3的指针赋给pfun
  23. test my_test;
  24. my_test.func1();
  25. my_test.func2(pfun); //把pfun传递给func2
  26. cin.get();
  27. }

输出结果为:
test func3.
test func3.


void fun(void (*pfun)());
 


原因:

这是因为类的成员函数是绑定到对象的,对于不同的对象,成员函数将会产生不同的拷贝,这样编译器就不知道把哪个拷贝传给fun了。这种情况在很多地方都会遇到,比如OpenCV里面的鼠标事件回调函数:

void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param CV_DEFAULT(NULL))
 

解决办法:


(1)把这个类改成普通的函数。这是最笨的办法。写成类的好处是可以在成员函数之间共享一些数据,如果改成普通的函数,那么就可能会定义一些全局变量来实现共享,而且也不便于管理。

(2)直接把要传递的函数声明为static类型,比如:

static void func3();
 


就是要把它调用到的所有成员(函数和变量)都声明为static类型 重载的虚函数
需要把所有它调用的成员也声明为static类型
最好的办法 是用一个友元(或者全局)函数把要传递的成员函数封装一层,将这个友元函数的函数指针传递给外部的普通函数,而在友元函数内调用该成员函数

程序如下:


  
  1. #include <iostream>
  2. using namespace std;
  3. class test
  4. {
  5. public:
  6. friend void friend_fun(void *obj); // 声明一个友元函数
  7. // main中调用外部函数
  8. //void call_fun()
  9. //{
  10. // outside_fun(friend_fun, this); // ☆ 把友元函数的指针和this指针传递给外部函数 ☆
  11. //}
  12. private:
  13. // 私有成员函数
  14. void private_fun()
  15. {
  16. cout<<"test private_func."<<endl;
  17. }
  18. };
  19. // ☆ 在 友元函数 中封装调用 私有成员函数private_func ☆
  20. void friend_fun(void *obj)
  21. {
  22. ((test*)obj)->private_fun();
  23. }
  24. // ☆ 用友元函数 优于 用static函数 ☆
  25. // 外部的普通函数,接受一个函数指针和一个void指针作为参数,比如多线程的执行函数
  26. void outside_fun(void (*pfun)(void *data), void *data)
  27. {
  28. (*pfun)(data);
  29. }
  30. int _tmain(int argc, _TCHAR* argv[])
  31. {
  32. test* my_test = new test;
  33. //my_test->call_fun();
  34. outside_fun(friend_fun, (void*)my_test);
  35. // 暂停
  36. cin.get();
  37. return 0;
  38. }

输出结果为:
test private_func.



文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/12013251

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。