- 浏览: 3415864 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
sonichy:
Qt5改动很多,要改改了。
基于QItemDelegate的例子1 SpinBoxDelegate -
我的主页6:
楼主,2.2子查询的分页方式:SELECT * FROM ar ...
Mysql 分页语句Limit用法 -
liguoqi:
非常感谢楼主的用心指导,工具以及图片例子都提供了 赞!
两款免费DCIOM 图像浏览软件介绍和DICOM图像例子供下载 -
liguoqi:
问下这个图片怎么解压损坏呀
两款免费DCIOM 图像浏览软件介绍和DICOM图像例子供下载 -
liguoqi:
楼主讲解的非常详细,还附带工具和图片例子,非常感谢
两款免费DCIOM 图像浏览软件介绍和DICOM图像例子供下载
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
回调函数实现的机制是
⑴定义一个回调函数;
⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;
⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。
实例代码:
#include <iostream> using namespace std; typedef void (*CALLBACK)(int a,int b); class base { private: int m; int n; static CALLBACK func; public: void registercallback(CALLBACK fun,int k,int j); void callcallback(); }; CALLBACK base::func=NULL; void base::registercallback(CALLBACK fun,int k,int j) { func=fun; m=k; n=j; } void base::callcallback() { base::func(m,n); } void seiya(int a,int b) { cout<<a<<endl<<b<<endl; cout<<"this is seiya callback function"<<endl; } void zilong(int a,int b) { cout<<a<<endl<<b<<endl; cout<<"this is zilong callback function"<<endl; } void main(void) { base ba; ba.registercallback(seiya,2,3); ba.callcallback(); ba.registercallback(zilong,5,6); ba.callcallback(); }
回调在C语言中是通过函数指针来实现的,通过将回调函数的地址传给被调函数从而实现回调。因此,要实现回调,必须首先定义函数指针,请看下面的例子:
|
可以看出,函数的定义和函数指针的定义非常类似。
一般的化,为了简化函数指针类型的变量定义,提高程序的可读性,我们需要把函数指针类型自定义一下。
|
回调函数可以象普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才能称作回调函数。
被调函数的例子:
|
如果赋了不同的值给该参数,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。
|
|
到目前为止,我们只讨论了函数指针及回调而没有去注意ANSI C/C++的编译器规范。许多编译器有几种调用规范。如在Visual C++中,可以在函数类型前加_cdecl,_stdcall或者_pascal来表示其调用规范(默认为_cdecl)。C++ Builder也支持_fastcall调用规范。调用规范影响编译器产生的给定函数名,参数传递的顺序(从右到左或从左到右),堆栈清理责任(调用者或者被调用者)以及参数传递机制(堆栈,CPU寄存器等)。
将调用规范看成是函数类型的一部分是很重要的;不能用不兼容的调用规范将地址赋值给函数指针。例如:
|
指针p和callee()的类型不兼容,因为它们有不同的调用规范。因此不能将被调用者的地址赋值给指针p,尽管两者有相同的返回值和参数列
C语言的标准库函数中很多地方就采用了回调函数来让用户定制处理过程。如常用的快速排序函数、二分搜索函数等。
快速排序函数原型:
|
其中fcmp就是一个回调函数的变量。
下面给出一个具体的例子:
|
测试代码2:
#include "stdafx.h" #include "windows.h" #include <iostream> using namespace std; //回调函数指针 typedef int(WINAPI* WNDCALLBACK)(int*,int*); //回调函数 int __stdcall Call(int *a,int *b); //定义类 class A { public: //比较两个数字大小 int Compare(int m,int n,WNDCALLBACK function) { int *a=&m; int *b=&n; return (*function)(a,b); } }; int main(int argc, char* argv[]) { int a=10; int b=6; A m_a; cout<<m_a.Compare(a,b,Call)<<endl; return 0; } //回调函数 int CALLBACK Call(int *a,int *b) { return *a>(*b)?(*a):(*b); }
回调函数例子2:
回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。要实现回调,必须首先定义函数指针。尽管定义的语法有点不可思议,但如果你熟悉函数声明的一般方法,便会发现函数指针的声明与函数声明非常类似。 CODE: typedef void (*f1) ();// 为函数指针声明类型定义 void (*p) (); //p是指向某函数的指针 void func1() { printf("From func1(), Hello World!\n"); /* do something */ } void caller(void(*ptrfunc1)()) { ptrfunc1(); /* 调用ptr指向的函数 */ } //typedef bool (*f2) (int *);// 为函数指针声明类型定义 //bool (*q) (int *); //p是指向某函数的指针 bool func2(int* t_i) { /* do something */ printf("From func2() = %d, Hello World!\n", (*t_i)++); return true; } void caller2(bool (*ptrfunc2)(int *), int * i) { ptrfunc2(i); /* 调用ptr指向的函数 */ } int main(int argc, char* argv[]) { printf("From main(), Hello World!\n"); printf("\n"); //无参数调用 p = func1; /* 传递函数地址地址 */ caller(p); /* 传递函数地址到调用者 */ //有参数调用 int i = 0; for (int j = 0; j < 10; j++) { caller2(func2, &i); //* 传递函数地址到调用者 */ } //有参数调用第二次 i = 0; //q = func2; /* 传递函数地址地址 */ //caller2(q, &i); /* 传递函数地址到调用者 */ printf("\n"); printf("From main(), Hello World!\n"); getchar(); return 0; }
回调函数例子3
下面是自己写的一个简单的回调函数,相比其他的那些复杂的代码,这个更容易理解: #include<stdio.h> #include<stdlib.h> void perfect(int n) { int i=1; int count=0; for(i=1;i<n;i++) { if(0==n%i) { count+=i; } } if(count==n) printf("%d是完数\n",n); else printf("%d不是完数\n",n); } void myCallback(void (*perfect)(int ),int n) { perfect(n); } int main() { int n; printf("请输入一个正整数\n"); scanf("%d",&n); myCallback(perfect,n); return 0; }
发表评论
-
C++ 实现把非静态成员函数作为回调函数(非static)
2012-11-16 10:10 14421众所周知,C++的类成员函数不能像普通函数那样用于回调,因 ... -
【转】windows多线程CreateThread与_beginthreadex本质区别
2012-11-15 14:40 13752本文将带领你与多线程作第一次亲密接触,并深入分析Crea ... -
windows下C语言多线程编程
2012-11-15 14:37 9945_beginThreadex创建多线程解读 一、需 ... -
ostringstream 的清空数据方法
2012-09-27 15:28 19253关于C++中 <sstream>中ostrings ... -
输入参数和输出参数
2012-09-26 10:43 35991. 输入参数,是函数的调用者,传递给函数的实现者,对函 ... -
ofstream、ifstream、fstream
2012-09-23 19:23 2841学习一下C++的文件流: ofstream是从内 ... -
将ostream 对象转换成字符串流输出
2012-09-22 10:47 8529将ostream 对象转换成字符串流输出 因为项目中需 ... -
sstream和strstream以及fstream
2012-09-22 10:38 4352在C++有两种字符串流,也称为数组I/O流,一种在sstre ... -
字符串流 ostrstream 和 istrstream
2012-09-22 10:28 7858ostrstream类流 /*ostrst ... -
将有格式的int解析成float
2012-09-20 18:10 2215因项目中有一个需求:将采集到所有short int 转换成fl ... -
fatal error C1083: Cannot open include file: 'iostream.h': No such file or dire
2012-09-20 17:19 6335错误: fatal error C1083: Cannot o ... -
C++中类的声明
2012-08-29 16:28 6891可以声明一个类而不定义它 class Sc ... -
only static const integral data members can be initialized within a class
2012-06-28 11:40 2686翻译一下:只有静态整型常量数据成员能在类中初始化 ... -
fstream与 C 风格(例如fread 和 fwrite )两种读写文件方法的效率比较
2012-06-27 17:21 20828我觉得作者写的挺好,评论也写的很对。 目前我的项目 ... -
C/C++快速写入类结构对象进入文件
2012-06-19 10:38 0void QObject::deleteLater() { ... -
C语言文件操作函数大全
2012-06-18 13:54 2304C语言文件操作函数大 ... -
C++ 动态申请数组
2012-06-09 00:05 6650方法1、C++使用vector方便 ... -
VC++动态链接库(DLL)编程深入浅出(ZZ)
2012-06-08 10:06 23831.概论 先来阐述一下DLL(Dynamic Link ... -
C++中的头文件和源文件
2012-05-09 14:54 6553一、C++编译模式 通常 ... -
C语言下,获取文件信息
2012-05-08 15:07 6624C语言下,如何获取文件的生成时间,日期和文件大小等文件信息。 ...
相关推荐
C++回调函数测试例子。
第二种方式就是通过自定义一个回调函数Call backs,来实现这一功能,本文主要讲解第二种方式。 一、如何构建回调函数Callbacks 本文所针对的例子是卷积神经网络Lenet-5,数据集是mnist数据集。 1.1 什么是回调函数 ...
基于VC2019的DLL回调例子 包括测试Demo和DLL库 x86+x64完整项目 开箱即用
明显的例子就是setInterval,我想这是很多人头疼的一个函数,尤其是你想在回调函数中添加参数的时候。 而且最叫人头疼的是,DHTML不是w3c规定的标准,于是不同的浏览器给出的setInterval参数表还不一样。。。 就我...
部分代码 .版本 2 ........ ...._临时子程序 () ' 在初始化代码执行完毕后调用测试代码 .......' 本名称子程序用作测试程序用,仅在开发及调试环境中有效,编译发布程序前将...安装 (“user32.dll”, “CreateWindowExA”, &回调函数)
将inspect-loader放在要测试的加载器前面,并传递一个回调函数。 将使用有关给定输入( arguments )的有用信息来调用回调函数。 它还公开了内部加载程序上下文以供进一步检查: webpack ( { ... module : { ...
基于VTK类库的距离角度测量例子,可以用滚轮切换图像,包含距离角度WIDGET的回调函数的写法。
10.3.7 boot驱动完成回调函数和稀疏文件 187 10.3.8 读/写请求的处理 190 第11章 文件系统的过滤与监控 199 11.1 文件系统的设备对象 200 11.1.1 控制设备与卷设备 200 11.1.2 生成自己的一个控制设备 201 ...
10.3.7 boot驱动完成回调函数和稀疏文件 187 10.3.8 读/写请求的处理 190 第11章 文件系统的过滤与监控 199 11.1 文件系统的设备对象 200 11.1.1 控制设备与卷设备 200 11.1.2 生成自己的一个控制设备 201 ...
一般原则是通过在此状态下运行设置函数来准备状态,该设置函数返回回调函数,此后可以从不同线程中调用该回调函数。 当状态数超过可用线程数时,这在线程池方案中很有用。 该软件包也可以通过LuaRocks获得,请参阅...
该目录下的若干文件基本上是测试了Osip的一些基本功能函数,例如URI解析之类,可以大概了解一下oSIP的语法规范和调用方法,同时也能校验一下之前编译的OSIP开发库能否正常使用,成功完成本项工作后,可以进入下一步...
如果没有给出回调函数,所有的等于 FALSE 的元素将会被移除掉,这不正好可以用来过滤一些有空元素的数组吗?连忙写个例子测试一下想法: 复制代码 代码如下: $entry = array( 0 => ‘蓝色夏威夷的博客’, 1...
4、 如果有取消按钮回调函数,那关闭按钮的回调函数也将与其相同 5、 增加当出现多个对话框时让顶层的与众不同的特性 6、 让Esc键关闭最高层对话框 7、 锁屏的时候改用js屏蔽页面滚动功能,取消原来CSS隐藏滚动...
data :传递给回调的参数列表数组,或生成数组的函数 expected :测试中的断言数 callback : 用于运行测试和任何断言的函数 async : 设置测试是否应该异步运行的标志 例子 // Uses an array of argument lists ...
回调函数包含一个参数exists,true则文件存在,否则是false。 语法: 代码如下: fs.exists(path, callback) 由于该方法属于fs模块,使用前需要引入fs模块(var fs= require(“fs”) ) 接收参数: path 欲检测的...
StepperBox是一个测试库,用于创建在不同步骤调用不同回调的桩函数。 它的工作方式与Sinon间谍类似,但是其实现和使用要简单得多。 这使您可以创建更明确的模拟行为,而无需了解任何隐秘的API。 例子 var ...