快乐小胖兔的一窟

用自己的方式过一生 --- zyq654321

VC知识库BLOG 首页 新随笔 联系 聚合 登录
  23 Posts :: 0 Stories :: 95 Comments :: 2 Trackbacks

公告

Welcome you

留言簿(4)

随笔分类

随笔档案

文章档案

相册

网站联接

BLOG友情链接

搜索

最新评论

阅读排行榜

评论排行榜

       我们都已经很熟悉回调函数了。通俗的讲,回调函数就是这样一种函数,调用者告诉服务者回调函数的地址,然后当某类事件发生时服务者会调用此函数。它也成为C/C++程序设计中一个有效的交互方式。根据C++面向对象的特性,回调函数在解决某些问题时就显得不够用了。例如有Serverclient两个类,当程序运行后,会出现多个它们的实例,且每个serverclient实例是一一对应的。这时我们要求当server实例发生某种事件时去调用client指定的一个函数(比如client的成员函数),此时用传统的回调函数就不行了,因为每个serverclient实例在实际运行中其属性或内容及行为已经不同了。确实的说,应该使用回调成员函数。基础C++对象封装性的特点,我写了一个回调类来实现类似功能。

//////////////////////////////////////////////////////////////////////////////

// CCallbackBase

class CCallbackBase

{

public:

     virtual BOOL NotifyToObject(UINT uMessage, WPARAM wParam, LPARAM lParam) = 0;

};

//////////////////////////////////////////////////////////////////////////////

// CCallbackClass

template<class T>

class CCallbackClass : public CCallbackBase

{

public:

     CCallbackClass()   {    m_fNotify  = 0; }

     ~CCallbackClass()  {    };

     typedef BOOL (T::*NOTIFYFPtr)(UINT uMessage, WPARAM wParam, LPARAM lParam);

     //------------------------------------------------------------------------

     // SetCallback

     void SetCallback(T* pObject, NOTIFYFPtr fNotify)

     {

         m_pObject = pObject;

         m_fNotify     = fNotify;

     }   

     //------------------------------------------------------------------------

     // Notify

     virtual BOOL NotifyToObject(UINT uMessage, WPARAM wParam, LPARAM lParam)

     {

         if(m_fNotify)

         {

              return (static_cast(m_pObject)->*m_fNotify)(uMessage, wParam, lParam);

         }

         else

         {

              return FALSE;

         }

     }

private:

     T*           m_pObject; // store pointer to the chip object

     NOTIFYFPtr   m_fNotify;     // member pointer variable   

 

};

可以这样实例化一个回调类:

class A

{

     ....

     private:

     CCallbackClass m_Callback;

    

    BOOL CallbackSample(UINT uMessage, WPARAM wParam, LPARAM lParam);

 

     void initCallback()

     {

         m_Callback.SetCallback(this, &A::CallbackSample);

     }

};

然后将回调类的实例指针传给Server端,这样Server端就可以在须要的时候执行client的回调成员函数了。

m_pPCICallback->NotifyToObject(NAME_CHANGE, 0, (LPARAM)(LPCTSTR)tcsText);

这样就是可以在很好的保证对象的封装性的条件下实现函数回调。

posted on 2004-11-03 02:46 Hercules Blog 阅读(2599) 评论(5)  编辑 收藏

Feedback

# re: 回调类的实现例子 2004-11-17 00:35 hsy
写的好,正是我想要的,谢谢!
是从设计模式的command模式总结出来的吧。

# re: hsy 2004-11-17 01:13 zyq654321
呵呵,谈不上总结。是工作中要用回调,写出来的。

# re: 回调类的实现例子 2006-05-14 17:27 yys
GoF的设计模式的command模式中的SimpleCommand,我是传递的成员函数,不知道会不会有很大局限性?

“是工作中要用回调,写出来的。”------强人呀!
偶是学习中要用回调,四处google.......

学习ing

# re: 回调类的实现例子 2006-05-14 19:11 yys
class A
{    ....
     private:
     CCallbackClass m_Callback;
    BOOL CallbackSample(UINT uMessage, WPARAM wParam, LPARAM lParam);
     void initCallback()
     {
         m_Callback.SetCallback(this, &A::CallbackSample);
     }
};
//\
这里的UINT uMessage, WPARAM wParam, LPARAM lParam从哪里传进来呀?

# re: yys 2006-05-15 10:50 zyq654321
yys, 当然是调用方传入的.用这三个参数是打个比方,可以有一定的通用性.

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]