时间:2021-05-20
前言
C++中使用class语法实现回调(当然,,旧式的C函数指针回调也是支持的)
比如,有人提供一个类库 AfCopyFile,能够提供文件拷贝的功能,而且能通知用户当前的进度。。。
用户只需要自己实现一个AfCopyFileListener对象,传给这个函数就行。。。
把Listener对象传过去
回调机制的缺点:
无论是C语言的回调函数,还是C++里的Listener,都有一个共同的缺点:
它使代码逻辑变得难以阅读。。
我们应尽量避免使用回调机制,最好采用单向的函数调用。
示例代码:
AfCopyFile.h
#ifndef _AF_COPY_FILE_H#define _AF_COPY_FILE_Hclass 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);};#endifAfCopyFile.cpp
#include <stdio.h>#include <Windows.h>#include "AfCopyFile.h"// 将LARGE_INTTEGER类型转成unsigned long longinline 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;}总结
以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
c++回调之利用函数指针示例复制代码代码如下:#includeusingnamespacestd;/******************************
委托(delegate)是一种可以把引用存储为函数的类型,这类似于c++中的函数指针。回调函数c++中的回调函数,就是用函数指针来实现的。类似的,c#中用委托,
C++中回调函数及函数指针的实例详解如何获取到类中函数指针实现代码://A类与B类的定义classA{public:voidTest(){cout
本文实例分析了C++中回调函数(CallBack)的用法。分享给大家供大家参考。具体分析如下:如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就
C++中回调函数详解及简单实例回调函数调用关系图对于第一种情况,主程序可以从执行到回调函数,也可以不执行回调函数,关键看宿主函数是否调用了回调函数。对于第二种情