回调函数的必要性? 和直接在函数A内调用函数B的区别?

registercsdn 2018-11-02 08:19:16
1.
第一种情况:
把函数B做为一个参数传给函数A, 在A里面执行完特定操作后,再执行B函数,此时B被称为回调函数。

第二种情况:
那么,即使不把B当作参数传给A,在A执行完特定操作后,也可以执行B,那么回调函数的必要性在哪里?


2.
看到在讨论用形参和实参来比拟回调函数传指针,
但是两者由很大的不同,
传递实参,是因为每个实参对应一个值,都可以不一样。
传递函数指针,函数所对应的是一种功能,可是不论如何传递,函数是执行相同的功能。
所以网上看到这个比拟也不是很理解。请解惑,感谢。
...全文
2653 58 打赏 收藏 转发到动态 举报
写回复
用AI写文章
58 条回复
切换为时间正序
请发表友善的回复…
发表回复
leekingly 2018-11-24
  • 打赏
  • 举报
回复
感觉看完一遍加深了理解
qq_35434869 2018-11-24
  • 打赏
  • 举报
回复
谢谢楼主的分享
lin5161678 2018-11-20
  • 打赏
  • 举报
回复
你得自己写函数A才能决定在函数A内部调用函数B
如果函数A不是你写的呢
weixin_43746922 2018-11-20
  • 打赏
  • 举报
回复
多态的函数表现
1021DL 2018-11-18
  • 打赏
  • 举报
回复
回调函数用在A不知道什么时候会调用B的情况下使用,A会在有特定事件发生的情况下才调用B。
weixin_43726466 2018-11-18
  • 打赏
  • 举报
回复
好像懂了谢谢谢~
  • 打赏
  • 举报
回复
回调函数是一种编程风格,在一些设计模式中,可以大大降低代码量。但从多年开发经验来看,能够使用类似事件或者信号-槽的时候,还是要避免大量使用回调函数。跨线程使用回调也是大坑。消息队列太重量了,一般用信号-槽以及事件的情况比较多。可能是习惯问题。
qisoft1213 2018-11-17
  • 打赏
  • 举报
回复
ajax请求给servlet,servlet将处理后的结果响应给ajax,由ajax里的function再处理,这个function就是典型的回调函数。
peiyuan1 2018-11-17
  • 打赏
  • 举报
回复 3
我看了一下前面的回复,都没有正确回答你的疑惑,你的疑惑是有什么必要使用函数指针,为什么要使用这样的技术来实现调用,直接将函数名称写到代码里面岂不更方便。那么我来回答你: 代码需要复用,可维护,在一个项目里面撰写了这个代码文件,在第二个项目里面很可能也要使用,但第二个项目里面所需要调用的函数却不一样,这时候就应该使用函数指针来实现它,因为这个文件并不知道该函数的名称。 举例如下:有2个排序程序,第一个项目里面排序对象是一堆整形数,第二个项目里面是一堆字符串。 我们在第一个项目实施时首先撰写了“排序.C”文件,再撰写了“INTCOMP.C文件”,将INTCOMP.C文件里面的INTCOMP函数通过指针告诉了排序函数。于是这个项目正确完成了排序工作。 可是在做第二个项目时,发现又要排序,但是排序对象却变成了一堆字符串,于是将以前项目里面的“排序.C”文件拷贝过来了,不需要做任何修改,同时新创建了"STRCOMP.C"的文件,将"STRCOMP.C"文件里面的STRCOMP函数通过指针告诉了排序函数。于是这个项目正确完成了排序工作。 你看这两个项目,我们将一个功能集成在一个文件里面,但该模块文件不需要做任何修改,这种方法很好地实现了代码的移植。
xuzuning 2018-11-17
  • 打赏
  • 举报
回复
形参是函数定义时声明的参数,他并不真实存在。比如 张三
实参是函数调用时实际传递的参数,比如 李四
函数并不知道 李四 的存在,都把他当作 张三 来处理

回调函数一定是传递函数指针(函数体所在的内存位置),你一定也不会希望将函数体在内存中搬来搬去的

关于回调函数
第一种情况:
把函数B做为一个参数传给函数A, 在A里面执行完特定操作后,再执行B函数,此时B被称为回调函数。

为什么不会是在 A里面执行一半时执行B函数呢?

第二种情况:
那么,即使不把B当作参数传给A,在A执行完特定操作后,也可以执行B,那么回调函数的必要性在哪里?

A在执行B时会携带A处理后的中间结果,若在A执行完后执行B,由谁去传递 A 的中间结果呢?或是说这个中间结果从何而来呢?

回调函数的真正意义在于:函数A通过回调函数B打成了允许调用者干预自己运行流程的目的
比如你写了个升序排序程序,现在却需要一个降序的,那么你会去复制一遍代码,仅把原来的 > 该成 < 吗?
如果你把比较大小的算法通过回调函数传入呢,是不是就不需要再去修改函数代码了呢?
dimscsdnaccount 2018-11-17
  • 打赏
  • 举报
回复
说一下我的观点:回调函数的本质是让代码更清晰精悍,这跟多态类似,事实上我们可以不写重载函数什么的,用函数1,函数2这么分别写最后一样阔以实现目的,但是代码冗长,编译起来估计也很蛋疼。
领域灬alone 2018-11-16
  • 打赏
  • 举报
回复
函数调用是需要创建函数栈的,建议比较下函数调用以及回调的堆栈变化
菲菲1586 2018-11-15
  • 打赏
  • 举报
回复 1
回调是为了解耦。解耦软件设计中常用的工具,但是解耦本身也是有使用场景的,不是任何情况都适合使用的。对于应用层代码,过度解耦只会增加程序复杂程度,而没有其他的好处。在这种情况下,回调用处不大。但是在其他一些场景,回调的是非常有用的。
chl00100 2018-11-15
  • 打赏
  • 举报
回复
sorry,上个帖子不小心ctrl+回车了,接着说:
当你开发一个流媒体接入100路摄像头视频流的时候,视频帧从采集模块传给业务模块时,如果不用回掉,就需要查询获取,实时要求是每秒钟查询100*25次,线程循环中,usleep少了,查询过快,数据没准备好,浪费cpu资源,usleep慢了,有可能丢帧,这时就需要缓存,代码复杂,资源浪费,显然是不适合的,而回调函数为通知机制,效率会高很多,省去了循环查询环节。
chl00100 2018-11-15
  • 打赏
  • 举报
回复
做摄像头和流媒体开发的,举一个必须用回调的例子:
xiaohuh421 2018-11-15
  • 打赏
  • 举报
回复 1
回调的意义我理解的至少有两个: 1. 异步处理. 当一个处理非常耗时, 你又需要返回, 但你又不想UI界面卡死在那里等待. 回调函数就能满足你. 典型用例: http接口请求. 调用 http接口时, 内部开一个线程去处理http请求, 请求完成后, 使用回调通知调用者http请求的结果. void fun(url, callback) { 开启url线程,传入callbak 函数本身返回. } 这样,调用fun后, 不用等http请求有结果, 函数就返回了, 不会卡UI (按钮点击响应函数) 2. 标准业务逻辑处理. 假设你要做一个炮茶的业务逻辑. 假设跑茶分几步:1.取水, 2. 烧水, 3.放茶叶, 4冲水. 取水,可以有自来水,矿泉水, 纯净水. 烧水, 可以电池炉,电老虎,天然气,打火机 茶叶, 就更多了 冲水. 可以直接倒, 也可以耍一套杂技. 这时, 你就可以在程序里面实现好固定的4上步骤, 具体这4个步骤是怎么做的, 你就不用关心. 4个步骤就相当于4个回调, 4个回调的调用顺序(泡茶步骤)已经固定, 但 4个回调是如何实现的, 你不用关心. 他用什么水, 放什么茶叶, 你不用关心.
XIAo_o TAo_o 2018-11-14
  • 打赏
  • 举报
回复
为什么要用回调函数,因为他就是一种模式,把接口暴露
adu_add 2018-11-14
  • 打赏
  • 举报
回复
区别就是 没有B你也能运行


来自 微信公众号 C语言之美
wlokgood 2018-11-14
  • 打赏
  • 举报
回复
入门有必要,不错!
杀意已决 2018-11-14
  • 打赏
  • 举报
回复 1
引用 26 楼 tq1086 的回复:
这么做为了解除调用方和被调用方的直接依赖关系。在编写库和框架时比较常用,编写应用程序时这么做的必要性不大。可以参考模板模式,接口的具体实现由客户程序决定,框架只负责调用这个接口。比如做饺子,不管是什么馅,步骤都是擀皮、和馅、包饺子。框架把这些步骤封装起来,至于包什么馅的饺子,由客户决定。因此框架的代码往往类似

包饺子(客人)
{
擀皮();
和馅(客人.要求的馅料());
包();
}

这就需要回调。在编写应用程序时,需求通常是具体的,比如只做芹菜猪肉饺子,所以代码往往类似

包饺子()
{
擀皮();
和馅(芹菜猪肉);
包();
}

没有回调也没关系。

回调是为了解耦。解耦软件设计中常用的工具,但是解耦本身也是有使用场景的,不是任何情况都适合使用的。对于应用层代码,过度解耦只会增加程序复杂程度,而没有其他的好处。在这种情况下,回调用处不大。但是在其他一些场景,回调的是非常有用的。


前面几十楼,就你这个饺子和解耦直切要害
加载更多回复(38)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧