您的位置:首页 > 编程语言 > C语言/C++

关于c/c++ 中的函数指针

2008-07-02 03:11 585 查看
在 c 使用函数指针与 c++ 虚拟函数不同,尽管 virtual function 的本质也是函数指针。在用 c 设计时,尽管没有抽象设计,但通过使用函数指针留出 call back 接口,就可以把不同的动作从代码中剥离出去,从而使得代码更加通用。一个例子,如果某个查找程序中需要一个排序, 而有不同的排序算法以适应不同的场合。为了保证查找程序的通用性,必须假设程序对外部环境一无所知,这时可以使用函数指针 call back.
typedef void (* SortFunctionPtr)(int* data, int size);
bool Search(int key, int* data, int size, SortFunctionPtr sortFunction) {
...
if (sortFunction != NULL)
(*sortFunction)(data, size);
...
}
另一个例子是 dll 中回调:
typedef void (*CALLBACK)(short, short*, short);
typedef void (__stdcall * FUNCTIONBINDING)(CALLBACK);

class CEventLog
{
HINSTANCE__* m_hXXXX;
FARPROC m_pBindingRead;
FARPROC m_pBindingWrite;
static bool Write(short type, short * buffer, short count);
static bool Read(short type, short * buffer, short count);

}

CEventLog::CEventLog()
{
m_hXXXX = ::LoadLibrary("xxxxx.dll");
m_bLoadSuccess = m_hXXXX != NULL;
if (!m_bLoadSuccess) {
::MessageBox(NULL, "Error: Fail to load xxxxx.dll.", "Error", MB_ICONSTOP | MB_OK);
return;
}
m_pBindingRead = ::GetProcAddress(m_hXXXX, "BindingReadFunction");
m_pBindingWrite = ::GetProcAddress(m_ hXXXX, "BindingWriteFunction");

(* (FUNCTIONBINDING) m_pBindingRead)((CALLBACK) Read);
(* (FUNCTIONBINDING) m_pBindingWrite)((CALLBACK) Write);

这样,local 的Read, Write 函数被传递到 dll 中,让dll 可以调用 local 的不同 Read/Write 函数。

在 c++ 使用回调比较繁琐,因为成员函数被暗藏了一个 this 指针,用函数指针模板是一个常用的方法 ,不过必须指定类型,无法真正通用。另一个解决方法是把 this 指针传递给一个成员 static function,可以实现,不过代码看上去怪异。
....
typedef void (*PTR_CALLBACK)(void* sender, DWORD para);
class CDelegate
{
PTR_CALLBACK m_pCallBack;
void* m_pInstance;
public:
void SetEventHandler(void* pInstance, PTR_CALLBACK pCallBack)
{
m_pInstance = (CDelegate*) pInstance;
m_pCallBack = pCallBack;
}

void Invoke(void* sender, DWORD para)
{
if (m_pInstance != NULL && m_pCallBack != NULL)
(*m_pCallBack)(sender, para);
}

....
}

使用时:
class CMyClass
{
...
public:
CMyClass(CDelegate* delegate) { delegate->SetEventHandler(this, MyClass::OnEvent); }
voidDoSomething();
.....
static void OnEvent(void* sender, DWORD para);
}

void CMyClass::OnEvent(void* sender, DWORD para)
{
CMyClass* me = (CMyClass*) sender;
me->DoSomething();
}

这里有一个在 C++ 中不使用 static 函数实现的完整的callback:

#if !defined(_Class_Delegate_)
#define _Class_Delegate_

/*************************************************************************************************
Warning: Unsafe Code !!!
*************************************************************************************************/

#define SetEventHandler(instance, function) _SetEventHandler((instance), reinterpret_cast<PTR_CALLBACK>(function))

class CDelegate;
typedef void (CDelegate::*PTR_CALLBACK)(void* sender, DWORD para);

class CDelegate
{
PTR_CALLBACK m_pCallBack;
CDelegate* m_pInstance;

public:
CDelegate()
{
m_pCallBack = NULL;
m_pInstance = NULL;
}

void _SetEventHandler(void* pInstance, PTR_CALLBACK pCallBack)
{
m_pInstance = (CDelegate*) pInstance;
m_pCallBack = pCallBack;
}

void Invoke(void* sender, DWORD para)
{
if (m_pInstance != NULL && m_pCallBack != NULL)
(m_pInstance->*m_pCallBack)(sender, para);
}

void Cancel()
{
m_pInstance = NULL;
}

};

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: