回撥函式的簡單說明(註釋中已經詳細說明)
阿新 • • 發佈:2019-01-10
第一部分基本的回撥函式寫
// callback.cpp : 定義控制檯應用程式的入口點。 // 回撥函式就是一個通過函式指標呼叫的函式 // #include "stdafx.h" #include <iostream> void OutputSchedule1(int schedule, char* str) // 要被呼叫的函式最終形式(main間接呼叫) { std::cout<<"schedule1 = "<< schedule <<std::endl; std::cout<<"str1 = "<< str <<std::endl; } void OutputSchedule2(int schedule, char* str) // 要被呼叫的函式最終形式(main間接呼叫) { std::cout<<"schedule2 = "<< schedule <<std::endl; std::cout<<"str2 = "<< str <<std::endl; } // 以上部分可以包含在dll中,只要指定了callback的函式簽名即可(本例:滿足 void xxx(int, char*) 的函式) ////////////////////////////////////////////////////////////////////////// // 以下的部分可以是呼叫dll部分的程式碼 typedef void (*mCallback)(int schedule, char* str); // 定義一個指向函式的函式指標 void caller(mCallback p) // 在main中呼叫的形式(mian直接呼叫);p是一個指標 { // 呼叫之時,只要滿足 void xxx(int, char*) 的函式都可以用做引數傳入 // 具體的操作有最終傳到p的函式決定 (*p)(1, "xxvvc456cs89cs-cs"); } int _tmain(int argc, _TCHAR* argv[]) { caller(&OutputSchedule1); caller(&OutputSchedule2); return 0; }
第二部分類中的回撥函式寫法
// callback.cpp : 定義控制檯應用程式的入口點。 // 類成員的回撥函式實現,需要藉助類物件 // 寫法一 #include "stdafx.h" #include <iostream> class mClass { public: // 類中包含的是兩個函式的實現過程 void OutputSchedule1(int schedule, char* str) // 要被呼叫的函式最終形式(main間接呼叫) { std::cout<<"schedule1 = "<< schedule <<std::endl; std::cout<<"str1 = "<< str <<std::endl; } void OutputSchedule2(int schedule, char* str) // 要被呼叫的函式最終形式(main間接呼叫) { std::cout<<"schedule2 = "<< schedule <<std::endl; std::cout<<"str2 = "<< str <<std::endl; } }; // 以上部分可以包含在dll中,只要指定了callback的函式簽名即可(本例:滿足 void xxx(int, char*) 的函式) ////////////////////////////////////////////////////////////////////////// // 以下的部分可以是呼叫dll部分的程式碼 typedef void (mClass::*pMenberFunction)(int schedule, char* str); // 宣告的符合‘類成員型別’的函式指標 void caller(mClass* pObj ,pMenberFunction p) // 在main中呼叫的形式(mian直接呼叫);p是一個指標;pObj最終用於傳遞類物件 { // 呼叫之時,只要滿足 void xxx(int, char*) 的函式都可以用做引數傳入 // 具體的操作有最終傳到p的函式決定 (pObj->*p)(1, "xxvvc456cs89cs-cs"); } int _tmain(int argc, _TCHAR* argv[]) { mClass mItem; caller(&mItem, &mClass::OutputSchedule1); // 第二個引數p接受的變數是函式指標,注意是使用類中定義的函式名(類似泛稱),而非(確定的某一個)mItem的成員 caller(&mItem, &mClass::OutputSchedule2); return 0; }
// callback.cpp : 定義控制檯應用程式的入口點。 // 類成員的回撥函式實現,需要藉助類物件 // 寫法二 使用模板 #include "stdafx.h" #include <iostream> class mClass { public: // 類中包含的是兩個函式的實現過程 void OutputSchedule1(int schedule, char* str) // 要被呼叫的函式最終形式(main間接呼叫) { std::cout<<"schedule1 = "<< schedule <<std::endl; std::cout<<"str1 = "<< str <<std::endl; } void OutputSchedule2(int schedule, char* str) // 要被呼叫的函式最終形式(main間接呼叫) { std::cout<<"schedule2 = "<< schedule <<std::endl; std::cout<<"str2 = "<< str <<std::endl; } }; // 以上部分可以包含在dll中,只要指定了callback的函式簽名即可(本例:滿足 void xxx(int, char*) 的函式) ////////////////////////////////////////////////////////////////////////// // 以下的部分可以是呼叫dll部分的程式碼 template<typename T> // !!僅修改此處及下下行,使用template:T 來替換類名:mClass // 這樣,就不侷限為某一個類。只要類成員的形式滿足 void xxx(int, char*) 就可以使用這個callback函式:caller void caller(T* pObj, void(T::*p)(int schedule, char* str))// 在main中呼叫的形式(mian直接呼叫);p是一個指標;pObj最終用於傳遞類物件 { // 呼叫之時,只要滿足 void xxx(int, char*) 的函式都可以用做引數傳入 // 具體的操作有最終傳到p的函式決定 (pObj->*p)(1, "xxvvc456cs89cs-cs"); } int _tmain(int argc, _TCHAR* argv[]) { mClass mItem; caller(&mItem, &mClass::OutputSchedule1); // 第二個引數p接受的變數是函式指標,注意是使用類中定義的函式名(類似泛稱),而非(確定的某一個)mItem的成員 caller(&mItem, &mClass::OutputSchedule2); return 0; }
第三部分類中呼叫回撥函式,在呼叫者一方編寫操作內容(比如可用於進度值回撥)
// callback.cpp : 定義控制檯應用程式的入口點。
// 類成員的回撥函式實現,需要藉助類物件
// 在類(或dll)中傳值到main
// 比如:可以用於進度回撥
//
#include "stdafx.h"
#include <iostream>
class mClass
{
public:
typedef void(*mScheduleCallback)(int schedule, char* str);
void caller(mScheduleCallback p) // 在類(dll)中傳遞兩個引數(int schedule, char* str 亦即 1, "xxvvc456cs89cs-cs")給呼叫者
{ // 傳遞出去的了兩個引數的用途由呼叫者編寫的函式決定
p(1, "xxvvc456cs89cs-cs"); // 比如可以作為進度值回撥給呼叫者
}
};
// 以上部分可以包含在dll中,只要指定了callback的函式簽名即可(本例:滿足 void xxx(int, char*) 的函式)
//////////////////////////////////////////////////////////////////////////
// 以下的部分可以是呼叫dll部分的程式碼
void OutputSchedule1(int schedule, char* str) // 有呼叫者編寫的函式指標指向的本體,也就是此處的兩個引數的顯示操作(main間接呼叫)
{
std::cout<<"schedule1 = "<< schedule <<std::endl;
std::cout<<"str1 = "<< str <<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
mClass mItem;
mItem.caller(&OutputSchedule1); // 有無引用符號好像都可以,這個測試程式碼還看不出差異
return 0;
}