C++中如何实现回调的方法示例

 更新时间:2017年10月06日 11:36:07   作者:NiceBlueChai  
这篇文章主要给大家介绍了关于C++中如何实现回调的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用c++具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

前言

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

总结

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • C语言 数据结构中栈的实现代码

    C语言 数据结构中栈的实现代码

    这篇文章主要介绍了C语言 数据结构中栈的实现代码的相关资料,需要的朋友可以参考下
    2016-10-10
  • VC实现ODBC数据库操作实例解析

    VC实现ODBC数据库操作实例解析

    这篇文章主要介绍了VC实现ODBC数据库操作的方法,非常有实用价值,需要的朋友可以参考下
    2014-07-07
  • C++条件语句和条件运算符的使用方法讲解

    C++条件语句和条件运算符的使用方法讲解

    这篇文章主要介绍了C++条件语句和条件运算符的使用方法讲解,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C++11新特性“=default”,“=delete”的使用

    C++11新特性“=default”,“=delete”的使用

    =default、=delete 是C++11的新特性,分别为:显式缺省(告知编译器生成函数默认的缺省版本)和显式删除(告知编译器不生成函数默认的缺省版本),本文就来介绍一下如何使用
    2021-05-05
  • C/C++: Inline function, calloc 对比 malloc

    C/C++: Inline function, calloc 对比 malloc

    以下是对c/c++中的malloc函数与calloc函数的区别以及它们之间的联系进行了介绍,需要的朋友可以过来参考下
    2016-07-07
  • C++ 再识类和对象

    C++ 再识类和对象

    类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量;创建对象的过程也叫类的实例化。每个对象都是类的一个具体实例(Instance),拥有类的成员变量和成员函数
    2021-10-10
  • VS Code如何编写C/C++程序的实现步骤

    VS Code如何编写C/C++程序的实现步骤

    本文主要介绍了VS Code如何编写C/C++程序的实现步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • C++/STL实现判断平面内两条线段的位置关系代码示例

    C++/STL实现判断平面内两条线段的位置关系代码示例

    这篇文章主要介绍了C++/STL实现判断平面内两条线段的位置关系代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • C语言数据结构与算法之排序总结(二)

    C语言数据结构与算法之排序总结(二)

    这篇文章住要介绍的是选择类排序中的简单、树形和堆排序,归并排序、分配类排序的基数排序,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2021-12-12
  • 详解c++实现信号槽

    详解c++实现信号槽

    这篇文章主要为大家介绍了c++实现信号槽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12

最新评论