回呼函數的用法(類之間的通訊),回呼函數用法通訊
// ConsoleApplication3.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>#include <functional>using namespace std;//1 "方向盤" 類接收外部的操作, 把訊息傳到 "車" 類中, 車類把訊息傳入到 "輪子" 類上//(子類發訊息給父類)//2 "方向盤" 類接收外部的操作, 把訊息傳入到 "輪子" 類上//(子類發訊息給子類)//方向盤類class Steering{private:function<void(float)> m_steeringAction;public://設定回呼函數void setWheelConnectWithCar(function<void(float)> steeringAction){m_steeringAction = steeringAction;}//轉動方向盤void turn(float angle){cout<<"Steering turn "<<angle<<" angle"<<endl;m_steeringAction(angle);}};//輪子類class Wheel{public://轉動輪子方向void turn(float angle){cout<<"Wheel turn "<<angle<<" angle"<<endl;}};//車類class Car{public://雖然方向盤在車裡, 但是使用者可以直接對它進行操作Steering m_steering;Wheel m_wheel;Car(){setCarConnectWithWheel();}#if 1//1 "方向盤" 類接收外部的操作, 把訊息傳到 "車" 類中, 車類把訊息傳入到 "輪子" 類上//設定車和方向盤串連的函數void setCarConnectWithWheel(){std::function<void (float)> _fun = std::bind(&Car::steeringAction,this,std::placeholders::_1);m_steering.setWheelConnectWithCar(_fun);}//當轉動方向盤時, 會調用該函數, 然後改函數讓輪子轉動相應的角度void steeringAction(float angle){m_wheel.turn(angle);}#else//2 "方向盤" 類接收外部的操作, 把訊息傳入到 "輪子" 類上//設定車和方向盤串連的函數void setCarConnectWithWheel(){std::function<void (float)> _fun = std::bind(&Wheel::turn,&m_wheel,std::placeholders::_1);m_steering.setWheelConnectWithCar(_fun);}#endif};int _tmain(int argc, _TCHAR* argv[]){Car _car;//讓方向盤轉動30度_car.m_steering.turn(30);return 0;}
類內的成員函數怎作為回呼函數使用? 我希望可以通過回呼函數訪問這個類的執行個體
類的成員函數作為回調,必須把類成員指標和指向這個成員函數的指標一起傳過去;
如果不支援對類成員函數的回調,就要把這個函式宣告成類的靜態函數
回呼函數的用法與好處
函數調用形式本身沒有好壞之分
任何函數代碼如果有錯誤都可能導致軟體出問題,甚至導致崩潰
c 裡可以使用指標,函數指標
這就使程式可以更靈活
當 函數指標 做為函數的參數,傳遞給一個被調用函數,
被調用函數就可以通過這個指標調用外部的函數,這就形成了回調
windows程式中 WndProc 就是使用回調的典型形式
一般的程式中回呼函數作用不是非常明顯,可以不使用這種形式
最主要的用途就是當函數不處在同一個檔案當中,比如動態庫,要調用
其他程式中的函數就只有採用回調的形式
#include "stdio.h"
#include "conio.h"
int add(int a, int b);
int libfun(int (*pDis)(int a, int b));
int main(void)
{
int (*pfun)(int a, int b);
pfun = add;
libfun(pfun);
}
int add(int a, int b)
{
return a + b;
}
int libfun(int (*pDis)(int a, int b))
{
int a, b;
a = 1;
b = 2;
printf("%d", pDis(a, b));
}
現在這幾個函數是在同一個檔案當中
假如
int libfun(int (*pDis)(int a, int b))
是一個庫中的函數,就只有使用回調了,通過函數指標參數將外部函數地址傳入
來實現調用
函數 add 的代碼作了修改,也不必改動庫的代碼,就可以正常實現調用
便於程式的維護和升級