C++中如何實(shí)現(xiàn)回調(diào)的方法示例
前言
C++中使用class語(yǔ)法實(shí)現(xiàn)回調(diào)(當(dāng)然,,舊式的C函數(shù)指針回調(diào)也是支持的)
比如,有人提供一個(gè)類(lèi)庫(kù) AfCopyFile,能夠提供文件拷貝的功能,而且能通知用戶(hù)當(dāng)前的進(jìn)度。。。
int DoCopy(const char* source, const char* dst, AfCopyFileListener* listener);
用戶(hù)只需要自己實(shí)現(xiàn)一個(gè)AfCopyFileListener對(duì)象,傳給這個(gè)函數(shù)就行。。。
class MainJob : public AfCopyFileListener{
int OnCopyProgress(long long total,
long long transfered){
}
}
把Listener對(duì)象傳過(guò)去
AfCopyFile af; af.DoCopy(source, dst, this);
回調(diào)機(jī)制的缺點(diǎn):
無(wú)論是C語(yǔ)言的回調(diào)函數(shù),還是C++里的Listener,都有一個(gè)共同的缺點(diǎn):
它使代碼邏輯變得難以閱讀。。
我們應(yīng)盡量避免使用回調(diào)機(jī)制,最好采用單向的函數(shù)調(diào)用。
示例代碼:
AfCopyFile.h
#ifndef _AF_COPY_FILE_H
#define _AF_COPY_FILE_H
class AfCopyFile
{
public:
// 作為內(nèi)部類(lèi)
class Listener
{
public:
virtual int OnCopyProgress(long long total, long long transfered) = 0;
};
public:
int DoCopy(const char* source, const char* dst, Listener* listener);
};
#endif
AfCopyFile.cpp
#include <stdio.h>
#include <Windows.h>
#include "AfCopyFile.h"
// 將LARGE_INTTEGER類(lèi)型轉(zhuǎn)成unsigned long long
inline unsigned long long translate(LARGE_INTEGER num)
{
unsigned long long result = num.HighPart;
result <<= 32;
result += num.LowPart;
return result;
}
// 回調(diào)函數(shù)
// 注:要求將此函數(shù)用關(guān)鍵字CALLBACK修飾(這是Windows API的要求)
static DWORD CALLBACK CopyProgress(
LARGE_INTEGER TotalFileSize,
LARGE_INTEGER TotalBytesTransferred,
LARGE_INTEGER StreamSize,
LARGE_INTEGER StreamBytesTransferred,
DWORD dwStreamNumber,
DWORD dwCallbackReason,
HANDLE hSourceFile,
HANDLE hDestinationFile,
LPVOID lpData) // <- 這個(gè)就是上下文件對(duì)象
{
// 計(jì)算百分比
unsigned long long total = translate(TotalFileSize);
unsigned long long copied = translate(TotalBytesTransferred);
// 打印進(jìn)度
AfCopyFile::Listener* listener = (AfCopyFile::Listener*) lpData;
listener->OnCopyProgress(total, copied);
return PROGRESS_CONTINUE;
}
int AfCopyFile::DoCopy(const char* source, const char* dst, Listener* listener)
{
BOOL ret = CopyFileEx(source, dst,
&CopyProgress, // 待回調(diào)的函數(shù)
listener, // 上下文對(duì)象
NULL, 0);
return ret ? 0 : -1;
}
main.cpp
#include <stdio.h>
#include <string.h>
#include "AfCopyFile.h"
class MainJob : public AfCopyFile::Listener
{
public:
int DoJob()
{
strcpy(user, "shaofa");
strcpy(source, "c:\\test\\2.rmvb" );
strcpy(dst, "c:\\test\\2_copy.rmvb");
AfCopyFile af;
af.DoCopy(source, dst, this); // 將this傳過(guò)去
return 0;
}
int OnCopyProgress(long long total, long long transfered)
{
// 打印進(jìn)度
int percent = (int) ( (transfered * 100 / total) );
printf("[用戶(hù): %s], %s -> %s : 進(jìn)度 %d %%\n",
user, source, dst, percent);
return 0;
}
private:
char source[256];
char dst[256];
char user[64];
};
int main()
{
MainJob job;
job.DoJob();
return 0;
}
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)中棧的實(shí)現(xiàn)代碼
這篇文章主要介紹了C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)中棧的實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10
VC實(shí)現(xiàn)ODBC數(shù)據(jù)庫(kù)操作實(shí)例解析
這篇文章主要介紹了VC實(shí)現(xiàn)ODBC數(shù)據(jù)庫(kù)操作的方法,非常有實(shí)用價(jià)值,需要的朋友可以參考下2014-07-07
C++11新特性“=default”,“=delete”的使用
=default、=delete 是C++11的新特性,分別為:顯式缺省(告知編譯器生成函數(shù)默認(rèn)的缺省版本)和顯式刪除(告知編譯器不生成函數(shù)默認(rèn)的缺省版本),本文就來(lái)介紹一下如何使用2021-05-05
C/C++: Inline function, calloc 對(duì)比 malloc
以下是對(duì)c/c++中的malloc函數(shù)與calloc函數(shù)的區(qū)別以及它們之間的聯(lián)系進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下2016-07-07
VS Code如何編寫(xiě)C/C++程序的實(shí)現(xiàn)步驟
本文主要介紹了VS Code如何編寫(xiě)C/C++程序的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
C++/STL實(shí)現(xiàn)判斷平面內(nèi)兩條線段的位置關(guān)系代碼示例
這篇文章主要介紹了C++/STL實(shí)現(xiàn)判斷平面內(nèi)兩條線段的位置關(guān)系代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法之排序總結(jié)(二)
這篇文章住要介紹的是選擇類(lèi)排序中的簡(jiǎn)單、樹(shù)形和堆排序,歸并排序、分配類(lèi)排序的基數(shù)排序,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2021-12-12

