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