找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4626|回复: 3

关于函数指针的应用

[复制链接]
发表于 2010-12-30 18:17:55 | 显示全部楼层 |阅读模式
这两天用到了一个需要使用指针回调的地方。以前用函数指针,函数必须是静态的。对于类实例的函数指针,以前没有写过。于是查了点资料,找到了方法,但是没有boost的bind好使,不过代码较为简单,简单的满足一下应该足够了。
在这里记录一下,以后说不定有用
  1. #include "stdafx.h"
  2. class CFunData
  3. {
  4. public:
  5.         CFunData(int nBase) {m_nBase = nBase; };
  6.         ~CFunData() {};
  7.         void Run(int nRet)
  8.         {
  9.                 printf("[Run]base(%d), All(%d) OK!\n", m_nBase, m_nBase + nRet);
  10.         }
  11. private:
  12.         int m_nBase;
  13. };
  14. class CFPoint
  15. {
  16. public:
  17.         typedef void (CFunData::*FuncP)(int);
  18.         FuncP     m_FuncP;
  19.         CFunData* m_pFunData;
  20. public:
  21.         CFPoint() { m_pFunData = NULL; };
  22.         ~CFPoint() {};
  23.         bool Bind(CFunData* pFunData, FuncP pFn)
  24.         {
  25.                 m_pFunData = pFunData;
  26.                 m_FuncP = pFn;
  27.                 return true;
  28.         };
  29.         void Run(int nData)
  30.         {
  31.                 if(m_pFunData != NULL)
  32.                 {
  33.                         (m_pFunData->*m_FuncP)(nData);
  34.                 }
  35.         }
  36. };
  37. //void (CFunData::*FuncP)(int);
  38. //FuncP = &CFunData::Run;
  39. //(FunData.*FuncP)(10);
  40. int _tmain(int argc, _TCHAR* argv[])
  41. {
  42.         CFunData FunData1(10);
  43.         CFunData FunData2(20);
  44.         CFPoint  FPoint1;
  45.         CFPoint  FPoint2;
  46.         FPoint1.Bind(&FunData1, &CFunData::Run);
  47.         FPoint1.Run(20);
  48.         FPoint2.Bind(&FunData2, &CFunData::Run);
  49.         FPoint2.Run(15);
  50.         getchar();
  51.         return 0;
  52. }
复制代码



运行测试结果:
[Run]base(10), All(30) OK!
[Run]base(20), All(35) OK!
发表于 2011-1-17 15:14:06 | 显示全部楼层
不错,不知道有没有什么影响;
发表于 2011-1-19 15:27:02 | 显示全部楼层
本帖最后由 featherwit 于 2011-1-19 15:28 编辑

我觉得这样实现基本没啥问题,简单明了,效率也很高。
另外正好想起来前段时间弄个一个命令调用的小东西。和这个需求不同,我那个是要求一个全局的类实例调用若干个函数,主要是执行不同命令用的。
简单写下,是这么个意思。
  1. class CUserClass
  2. {
  3. public:
  4.     struct FolkFunction
  5.     {
  6.         virtual int operator() ( /*in and out paras*/ ) = 0;
  7.         //static const keyvaluetype key_;
  8.     };
  9.     typedef boost::shared_ptr<FolkFunction> FolkFunctionPtr;
  10.     typedef std::map<std::string, FolkFunctionPtr> FolkFunction_Colls;
  11.      
  12. protected:
  13.      FolkFunction_Colls m_folkmap;
  14.     template<typename FuncName>
  15.     void RegisterFunctions(FuncName);
  16. ...
  17. };
  18. //把这个类singleton化
  19. template<typename FuncName>
  20. inline void CUserClass::RegisterFunctions(FuncName)
  21. {
  22.     m_folkmap.insert(std::make_pair(FuncName::name_, FolkFunctionPtr(new FuncName())));
  23. }
  24. struct HelpFunc :
  25.     public CUserClass::FolkFunction
  26. {
  27.     virtual int operator() ( /*in and out paras*/ )
  28.     {
  29.         //do somthing
  30.     }
  31.     //static const keyvaluetype key_;
  32. };
复制代码
那个keyvaluetype是随便写的,根据我那边的需要写用的是string,就是命令对应函数,然后传一个参数列表到函数相应函数里面。
这东西的好处是别人实现其他的执行命令比较容易,注册的时候直接register(仿函数名称)就可以了。而且可以根据实际需要做一些他需要的初始化工作。比如在仿函数里面加上一些成员变量神马的。
至于效率...虽然可以不用template,有其他的实现方式...总之玩意儿效率肯定是不高就是了。

ps:这段时间去外地出差...我发誓我再也不出差了...
 楼主| 发表于 2011-1-19 18:40:41 | 显示全部楼层
非常好,呵呵,如果能分装成一个例子就更好了。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-5 12:26 , Processed in 0.023029 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表