关于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
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
相关文章推荐
- C/C++中关于地址、指针和引用变量的学习笔记(四) : 函数
- C++关于this指针、静态变量和静态成员函数
- 关于C++中函数指针的使用
- 关于C++中函数指针的使用
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- C++中关于指向对象成员函数打指针例子
- 关于C++中函数指针的使用
- 一劳永逸:关于C/C++中指针、数组与函数复合定义形式的直观解释
- C++初学者(关于函数指针的应用)
- c++ 关于类成员函数指针
- [原创] 一劳永逸:关于C/C++中指针、数组与函数复合定义形式的直观解释
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- 关于C++中类的成员函数指针相关问题
- 关于C++中函数指针的使用
- 【编程开发】 C与C++中的关于函数指针的强制类型转换与指针函数的关系
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- 关于c++ 函数指针的问题
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- 一劳永逸:关于C/C++中指针、数组与函数复合定义形式的直观解释
- 关于C++中函数指针的使用(包含对typedef用法的讨论)