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

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在CLR/C++,可以使用委托来实现函数指针的功能委托是一种类型安全的函数指针,可以用于引用和调用函数。以下是使用CLR/C++定义和使用委托的示例: ```cpp #include <iostream> // 定义委托类型 delegate void MyDelegate(int); // 示例函数1 void Function1(int value) { std::cout << "Function1 called with value: " << value << std::endl; } // 示例函数2 void Function2(int value) { std::cout << "Function2 called with value: " << value << std::endl; } int main() { // 声明委托变量 MyDelegate^ myDelegate; // 将委托绑定到函数1 myDelegate = gcnew MyDelegate(&Function1); // 调用委托,实际上调用了函数1 myDelegate->Invoke(10); // 将委托绑定到函数2 myDelegate = gcnew MyDelegate(&Function2); // 调用委托,实际上调用了函数2 myDelegate->Invoke(20); return 0; } ``` 在这个示例,我们首先使用`delegate`关键字定义了一个委托类型`MyDelegate`,它可以引用一个接受一个`int`参数并返回`void`的函数。 然后,我们定义了两个示例函数`Function1`和`Function2`,它们符合上述的委托类型。 在`main`函数,我们声明了一个名为`myDelegate`的委托变量。 我们将`myDelegate`绑定到`Function1`并调用它,然后将`myDelegate`绑定到`Function2`并再次调用它。 使用委托时,可以使用`Invoke`方法来调用委托,实际上是在调用委托所绑定的函数。 请注意,CLR/C++的委托与传统的C++函数指针有所不同。委托是一种引用类型,需要使用`gcnew`关键字进行实例化,并使用`^`符号来声明委托变量。委托还提供了更多的灵活性和功能,如多播委托和异步委托等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值