C++ 回調函數的多種用法


  什么是回調函數, 就是以函數指針做參數傳遞給另一個函數稱之為回調函數, 字面意思很簡單, 但就這幾個字想理解回調函數, 那又很難。因此別就這這字面意思, 只要知道怎么用, 在什么情況下用就行了

  什么場景下需要使用回調函數, 回調函數主要是完成通知功能, 例如我領導給我分配另外工作, 但是我手里工作又沒做完, 那領導總不可能沒過個幾個小時就跑過來問一下,這樣我們兩個人都很煩, 而在代碼中如果這樣實現(需要開一個線程, 不停的輪尋)也很消耗系統資源, 所以最好的辦法就是等我手里的工作完成了, 我自己去和領導說,然后進入下個工作任務, 而在我們代碼中想要這樣實現就需要通過回調函數來完成

  回調函數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更簡單,直接在員工類中和回調函數綁定在一起,回調函數的使用就簡述這么多了,希望對大家有所幫助




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM