網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
前言
回調(diào)函數(shù)其實(shí)和普通函數(shù)一樣,不同的是普通函數(shù)是直接在程序中進(jìn)行調(diào)用,回調(diào)函數(shù)是通過函數(shù)指針將它的地址傳遞給其它函數(shù),函數(shù)執(zhí)行在其它函數(shù)體執(zhí)行,這個(gè)過程就叫做回調(diào)。所以,C++回調(diào)函數(shù)也并非高大上的技術(shù),它的原理無非就是函數(shù)指針或者對(duì)象的傳遞。
回調(diào)函數(shù)機(jī)制:
1、定義一個(gè)函數(shù)(普通函數(shù)即可);
2、將此函數(shù)的地址注冊(cè)給調(diào)用者;
3、特定的事件或條件發(fā)生時(shí),調(diào)用者使用函數(shù)指針調(diào)用回調(diào)函數(shù)。
本文就從函數(shù)指針開始對(duì)回調(diào)函數(shù)進(jìn)行說明。
1 函數(shù)指針
函數(shù)指針是指一個(gè)變量,函數(shù)對(duì)象創(chuàng)建后就會(huì)分配一個(gè)地址,這個(gè)地址可以通過變量進(jìn)行保存。這個(gè)變量就叫做函數(shù)地址變量,也可以稱之為函數(shù)指針。
函數(shù)指針的定義方式如下:
int(*p)(int, int);
如上,定義了一個(gè)函數(shù)指針,它指向一個(gè)包含兩個(gè)整型參數(shù)且返回值為整型數(shù)值的函數(shù)對(duì)象。
函數(shù)指針在C和C++中被經(jīng)常使用,使用方式也很簡(jiǎn)單,具體如下面代碼所示:
typedef int (*Ptr)(int,int); int add(int a,int b){ return (a+b); } int main() { Ptr pInt = add; cout<<pInt(3,5)<<endl; return 0; }
2 C風(fēng)格的回調(diào)函數(shù)
上面的代碼是將一個(gè)函數(shù)地址賦值給了函數(shù)指針,下面將函數(shù)作為回調(diào)函數(shù)的參數(shù)的方式進(jìn)行處理,函數(shù)處理結(jié)果也是一致的。代碼如下:
typedef int (*Ptr)(int, int); int CallBack(Ptr pInt, int a, int b) { return pInt(a, b); } int add(int a, int b) { return (a + b); } int main() { cout << CallBack(&add, 3, 5) << endl; }
代碼如上,代碼運(yùn)行結(jié)果為:8。
實(shí)現(xiàn)是不是很簡(jiǎn)單,通過回調(diào)函數(shù),可以讓用戶自己定義自己的業(yè)務(wù)實(shí)現(xiàn),且這種方式在網(wǎng)絡(luò)通訊中被經(jīng)常使用,下面在看看一下如果回調(diào)函數(shù)是類成員函數(shù)的時(shí)候如何實(shí)現(xiàn)。
3 C++風(fēng)格的回調(diào)函數(shù)
在C++中,如果回調(diào)函數(shù)是類成員函數(shù),需要將回調(diào)函數(shù)定義成為靜態(tài)。當(dāng)然也可以使用全局函數(shù),但是這樣做就會(huì)破壞C++的封裝性。
下面的代碼就演示了將一個(gè)靜態(tài)成員函數(shù)作為回調(diào)函數(shù)的使用情況。
typedef int (*Ptr)(int,int); int RegFuncation(Ptr pInt,int a,int b){ return pInt(a,b); } class COperMath{ public: //回調(diào)函數(shù) static int add(int a,int b){ return (a+b); } //注冊(cè)函數(shù) void RegFuncationCallBack(){ cout<<RegFuncation(add,3,5)<<endl; return ; } }; int main() { COperMath pInst; pInst.RegFuncationCallBack(); return 0; }
4 多態(tài)類型的回調(diào)函數(shù)
在前面的代碼中,都是使用函數(shù)指針的方式進(jìn)行,下面的代碼使用多態(tài)的方式實(shí)現(xiàn),為了演示實(shí)現(xiàn)的方式,代碼比較簡(jiǎn)單。
class CAniable{ public: virtual void eat()=0; }; class CCat:public CAniable{ public: virtual void eat(){ cout<<"Cat like mouse"<<endl; } }; class CDog:public CAniable{ public: virtual void eat(){ cout<<"Dog like shit"<<endl; } }; int main() { CAniable *pBase = new CCat(); pBase->eat(); CAniable *pBase1 = new CDog(); pBase1->eat(); delete pBase; delete pBase1; return 0; }
代碼運(yùn)行結(jié)果為:
Cat like mouse
Dog like shit
上面的代碼通過定義一個(gè)純虛的基類,里面定義了一個(gè)純虛的公共接口,其它類都繼承自基類,在使用時(shí)就可以將這個(gè)類指針傳遞給回調(diào)函數(shù),進(jìn)而實(shí)現(xiàn)回調(diào)的功能。
5 通過function和bind實(shí)現(xiàn)回調(diào)函數(shù)功能
function功能很函數(shù)指針功能類似,不同的是function可以調(diào)用各種對(duì)象和函數(shù)。function還可以調(diào)用lamda表達(dá)式。具體如下所示。
typedef function<int(int,int)> func; int add(int a,int b){ return (a+b); } class COperMath{ public: float Sum(float a,float b){ return(a+b); } }; int main() { //function包裹add func f = &add; cout<<"func="<<f(3,5)<<endl; //function和bind聯(lián)合使用 COperMath cMath; function<float(float,float)> func_bind = bind(&COperMath::Sum,ref(cMath),placeholders::_1,placeholders::_2); cout<<"func_bind="<<func_bind(6.0,10.0)<<endl; return 0; }
代碼運(yùn)行結(jié)果為:
func=8
func_bind=16
如上,本文使用了5種方式對(duì)回調(diào)函數(shù)進(jìn)行實(shí)現(xiàn),在實(shí)際項(xiàng)目中,使用回調(diào)函數(shù)的場(chǎng)景比這里要復(fù)雜的多,希望大家在實(shí)際使用中能夠運(yùn)用自如。
6 總結(jié)
回調(diào)函數(shù)在實(shí)際中有許多作用。假設(shè)有這樣一種情況:我們要編寫一個(gè)庫(kù),該庫(kù)實(shí)現(xiàn)排序功能,但是又不希望在庫(kù)里實(shí)現(xiàn)排序邏輯,這樣就可以使用回調(diào)函數(shù)讓用戶自己通過函數(shù)指針的方式將排序邏輯傳進(jìn)來進(jìn)行排序。回調(diào)可用于網(wǎng)絡(luò)編程中,如通過回調(diào)函數(shù)獲取服務(wù)端返回的數(shù)據(jù)信息并進(jìn)行處理。
原文鏈接:https://mp.weixin.qq.com/s/D6RpbdhO5l19p7Bnexc9sQ
相關(guān)推薦
- 2022-07-18 C++函數(shù)模板和類模板詳解
- 2023-07-30 ES6 module語(yǔ)法中export和import的使用
- 2022-05-15 Qt windows打開資源管理器并高亮文件
- 2022-11-23 詳解如何使用Pytorch進(jìn)行多卡訓(xùn)練_python
- 2022-03-12 Android?ContentProvider基礎(chǔ)應(yīng)用詳解_Android
- 2022-07-14 Android實(shí)現(xiàn)手勢(shì)劃定區(qū)域裁剪圖片_Android
- 2022-09-15 SQL?bool盲注和時(shí)間盲注詳解_MsSql
- 2022-08-21 android實(shí)現(xiàn)貝塞爾曲線之波浪效果_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支