您好,登錄后才能下訂單哦!
前言
C++中使用class語法實現回調(當然,,舊式的C函數指針回調也是支持的)
比如,有人提供一個類庫 AfCopyFile,能夠提供文件拷貝的功能,而且能通知用戶當前的進度。。。
int DoCopy(const char* source, const char* dst, AfCopyFileListener* listener);
用戶只需要自己實現一個AfCopyFileListener對象,傳給這個函數就行。。。
class MainJob : public AfCopyFileListener{ int OnCopyProgress(long long total, long long transfered){ } }
把Listener對象傳過去
AfCopyFile af; af.DoCopy(source, dst, this);
回調機制的缺點:
無論是C語言的回調函數,還是C++里的Listener,都有一個共同的缺點:
它使代碼邏輯變得難以閱讀。。
我們應盡量避免使用回調機制,最好采用單向的函數調用。
示例代碼:
AfCopyFile.h
#ifndef _AF_COPY_FILE_H #define _AF_COPY_FILE_H class AfCopyFile { public: // 作為內部類 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類型轉成unsigned long long inline unsigned long long translate(LARGE_INTEGER num) { unsigned long long result = num.HighPart; result <<= 32; result += num.LowPart; return result; } // 回調函數 // 注:要求將此函數用關鍵字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) // <- 這個就是上下文件對象 { // 計算百分比 unsigned long long total = translate(TotalFileSize); unsigned long long copied = translate(TotalBytesTransferred); // 打印進度 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, // 待回調的函數 listener, // 上下文對象 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傳過去 return 0; } int OnCopyProgress(long long total, long long transfered) { // 打印進度 int percent = (int) ( (transfered * 100 / total) ); printf("[用戶: %s], %s -> %s : 進度 %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; }
總結
以上就是這篇文章的全部內容,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。