C++中如何实现回调的方法示例
前言
C++中使用class语法实现回调(当然,,旧式的C函数指针回调也是支持的)
比如,有人提供一个类库AfCopyFile,能够提供文件拷贝的功能,而且能通知用户当前的进度。。。
intDoCopy(constchar*source, constchar*dst, AfCopyFileListener*listener);
用户只需要自己实现一个AfCopyFileListener对象,传给这个函数就行。。。
classMainJob:publicAfCopyFileListener{
intOnCopyProgress(longlongtotal,
longlongtransfered){
}
}
把Listener对象传过去
AfCopyFileaf; af.DoCopy(source,dst,this);
回调机制的缺点:
无论是C语言的回调函数,还是C++里的Listener,都有一个共同的缺点:
它使代码逻辑变得难以阅读。。
我们应尽量避免使用回调机制,最好采用单向的函数调用。
示例代码:
AfCopyFile.h
#ifndef_AF_COPY_FILE_H
#define_AF_COPY_FILE_H
classAfCopyFile
{
public:
//作为内部类
classListener
{
public:
virtualintOnCopyProgress(longlongtotal,longlongtransfered)=0;
};
public:
intDoCopy(constchar*source,constchar*dst,Listener*listener);
};
#endif
AfCopyFile.cpp
#include#include #include"AfCopyFile.h" //将LARGE_INTTEGER类型转成unsignedlonglong inlineunsignedlonglongtranslate(LARGE_INTEGERnum) { unsignedlonglongresult=num.HighPart; result<<=32; result+=num.LowPart; returnresult; } //回调函数 //注:要求将此函数用关键字CALLBACK修饰(这是WindowsAPI的要求) staticDWORDCALLBACKCopyProgress( LARGE_INTEGERTotalFileSize, LARGE_INTEGERTotalBytesTransferred, LARGE_INTEGERStreamSize, LARGE_INTEGERStreamBytesTransferred, DWORDdwStreamNumber, DWORDdwCallbackReason, HANDLEhSourceFile, HANDLEhDestinationFile, LPVOIDlpData)//<-这个就是上下文件对象 { //计算百分比 unsignedlonglongtotal=translate(TotalFileSize); unsignedlonglongcopied=translate(TotalBytesTransferred); //打印进度 AfCopyFile::Listener*listener=(AfCopyFile::Listener*)lpData; listener->OnCopyProgress(total,copied); returnPROGRESS_CONTINUE; } intAfCopyFile::DoCopy(constchar*source,constchar*dst,Listener*listener) { BOOLret=CopyFileEx(source,dst, &CopyProgress,//待回调的函数 listener,//上下文对象 NULL,0); returnret?0:-1; }
main.cpp
#include#include #include"AfCopyFile.h" classMainJob:publicAfCopyFile::Listener { public: intDoJob() { strcpy(user,"shaofa"); strcpy(source,"c:\\test\\2.rmvb"); strcpy(dst,"c:\\test\\2_copy.rmvb"); AfCopyFileaf; af.DoCopy(source,dst,this);//将this传过去 return0; } intOnCopyProgress(longlongtotal,longlongtransfered) { //打印进度 intpercent=(int)((transfered*100/total)); printf("[用户:%s],%s->%s:进度%d%%\n", user,source,dst,percent); return0; } private: charsource[256]; chardst[256]; charuser[64]; }; intmain() { MainJobjob; job.DoJob(); return0; }
总结
以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。