1. 程式人生 > >回撥函式的簡單說明(註釋中已經詳細說明)

回撥函式的簡單說明(註釋中已經詳細說明)

第一部分基本的回撥函式寫

// 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;
}