C++的回调机制


什么是回调

开发中经常遇到等待其他模块事件通知的情况,例如:

  • 用户点击UI上button的事件,通知给相关函数处理逻辑
  • Model中数据改变的事件,通知给相关View模块刷新界面
  • 异步IO完成的事件,通知给处理函数确认成功还是失败
  • 客户端向服务器发N种不同请求,服务器为每种请求准备好处理函数

这些等待通知的函数被执行的过程就是回调的过程,所以回调是一个很常见很简单的事情。回调可能大家首先想到的是回调函数,回调机制包括但并不拒局限于回调函数(不过在C语言里两者基本相同),其核心思想就是由调用者实现部分甚至全部操作细节。这个思想的用途十分广泛。在设计良好的C++程序中,实现回调的最主要方法应该是多态。


实现方法

(1)Callback方式。

a.Callback的本质是设置一个函数指针进去,然后在需要需要触发某个事件时调用该方法, 比如Windows的窗口消息处理函数就是这种类型。(这就是C的回调函数而已,面向过程的,注意要使用全局函数


b.C++里面用类,记得定义成静态static成员,思想与上面一样。


为什么不能直接使用类的非静态函数作为回调函数呢,通俗点的解释就是类的非静态函数都要默认传入一个this指针参数,这就跟我们平时的回调不同了,所以无法使用。一般的回调函数都是_stdcall或者_cdecl的调用方式,但是成员函数是__thiscall的调用方式。这种调用方式的差别导致不能直接使用类的非静态成员函数作为回调函数。看看区别吧:

关键字

堆栈清除

参数传递

__stdcall

被调用者

将参数倒序压入堆栈(自右向左)

__thiscall

被调用者

压入堆栈,this指针保存在 ECX 寄存器中

可见两者的不同之处就是_thiscall把this指针保存到了ECX的寄存器中,其他都是一样的。


(2)采用C++的非静态成员函数实现

实现多态。(正统主流方法,大部分情况下考虑使用。太多设计模式采用这个体位了)


Sink方式。(面向对象的,在C++里使用较多, 可以在一个Sink里封装一组回调接口,适用于一系列比较固定的回调事件)
Sink的本质是你按照对方要求实现一个C++接口,然后把你实现的接口设置给对方,对方需要触发事件时调用该接口, COM中连接点就是居于这种方式。上面下载文件的需求,如果用Sink实现,代码如下:



©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页