什么是回調函數, 就是以函數指針做參數傳遞給另一個函數稱之為回調函數, 字面意思很簡單, 但就這幾個字想理解回調函數, 那又很難。因此別就這這字面意思, 只要知道怎么用, 在什么情況下用就行了
什么場景下需要使用回調函數, 回調函數主要是完成通知功能, 例如我領導給我分配另外工作, 但是我手里工作又沒做完, 那領導總不可能沒過個幾個小時就跑過來問一下,這樣我們兩個人都很煩, 而在代碼中如果這樣實現(需要開一個線程, 不停的輪尋)也很消耗系統資源, 所以最好的辦法就是等我手里的工作完成了, 我自己去和領導說,然后進入下個工作任務, 而在我們代碼中想要這樣實現就需要通過回調函數來完成
回調函數3要素
1: 定義一個函數指針(和回調函數的參數類型, 數量, 順序, 返回值全部一致)
2: 定義一個類成員靜態回調函數(備注:類成員 回調函數必須是static)
3: 回調函數和函數指針綁定在一起
回調函數用法1: C98回調函數寫法
//該類相當於上面例子中員工(我)的角色
#pragma once
//打印姓名相當於上面例子中的未完成的工作
#include <stdio.h> #include <string.h> using namespace std;
//定義一個函數指針 typedef void(*PrintName)(string strName); enum CallType { NAME, AGE, GRADE, }; class CallBack { public: CallBack(); ~CallBack(); public: void TestCallBack(CallType type); public: PrintName m_PrintName; }; #include "CallBack.h" CallBack::CallBack() { } CallBack::~CallBack() { } void CallBack::TestCallBack(CallType type) { switch (type) { case NAME: m_PrintName(string("name")); break; default: break; } }
//該類相當於上面例子中領導的角色
#include <memory> #include "CallBack.h" class BaseCall { public: BaseCall(); ~BaseCall(); public: //靜態的類成員函數 static void onPrintName(string strName); private: std::shared_ptr<CallBack> m_CallBack; }; BaseCall::BaseCall() { m_CallBack = make_shared<CallBack>(); //和回調函數綁定 m_CallBack->m_PrintName = onPrintName; m_CallBack->TestCallBack(NAME); } BaseCall::~BaseCall() { } void BaseCall::onPrintName(string strName) { printf("姓名: %s\n", strName.c_str()); }
上面就是C11之前的寫法, 比較復雜, 需要定義一個函數指針, 定義完之后還需要兩個綁定在一起, 而C11出來之后, 就是會簡化以前的復雜的編碼風格, 利用function, 和band函數能輕松的實現一個回調函數操作,
C11的回調函數用法
//該類相當於上面例子中員工(我)的角色using namespace std;
typedef void(*PrintName)(string strName); enum CallType { NAME, AGE, GRADE, }; class CallBack { public: CallBack(); ~CallBack(); public: void TestCallBack(CallType type); public: PrintName m_PrintName;
function<void(int)> m_PrintAge; //C11 寫法1 }; #include "CallBack.h" #include "BaseCall.h" CallBack::CallBack() { } CallBack::~CallBack() { } void CallBack::TestCallBack(CallType type) { switch (type) { case NAME: m_PrintName(string("name")); break; case AGE: m_PrintAge(100); break; case GRADE: {
// C11 寫法2 function<void(int)> printGrade = bind(BaseCall::onPrintGrade, placeholders::_1); printGrade(2019); } break; default: break; } }
//該類相當於上面例子中領導的角#include <memory>
#include "CallBack.h" class BaseCall { public: BaseCall(); ~BaseCall(); public: static void onPrintName(string strName); static void onPrintAge(int nAge); static void onPrintGrade(int); private: std::shared_ptr<CallBack> m_CallBack; }; BaseCall::BaseCall() { m_CallBack = make_shared<CallBack>(); m_CallBack->m_PrintName = onPrintName;
m_CallBack->m_PrintAge = bind(BaseCall::onPrintAge, placeholders::_1); //C11寫法1 m_CallBack->TestCallBack(NAME); m_CallBack->TestCallBack(AGE); m_CallBack->TestCallBack(GRADE); } BaseCall::~BaseCall() { } void BaseCall::onPrintName(string strName) { printf("姓名: %s\n", strName.c_str()); } void BaseCall::onPrintAge(int nAge) { printf("年齡: %d\n", nAge); } void BaseCall::onPrintGrade(int nGrade) { printf("班級:%d\n", nGrade); }
通過上面C11的function和band 2個函數能夠簡單實現函數回調, C11寫法是在領導類中和回到函數綁定在一起, 而寫法2更簡單,直接在員工類中和回調函數綁定在一起,回調函數的使用就簡述這么多了,希望對大家有所幫助