`
eriol
  • 浏览: 405483 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

回调函数(callback)和仿函数(functor)

    博客分类:
  • C++
阅读更多

回调函数(callback)与仿函数(functor)很多时候从用途上来看很相似,以致于我们经常将它们相提并论。例如:

 

inline bool compare(int a, int b)
{
   return a > b;
}
 
struct comparer {
  bool operator()(int a, int b) const {
     return a > b;
  }
};
 
void main()
{
   std::vector<int> vec, vec2;
   std::sort(vec.begin(), vec.end(), compare);
   std::sort(vec2.begin(), vec2.end(), comparer());
}

 

    仿函数(functor)之所以称为仿函数,是因为这是一种利用某些类对象支持operator()的特性,来达到模拟函数调用效果的技术。

    如果这里vec, vec2这两个vector的内容一样,那么从执行结果看,使用回调函数compare与使用仿函数comparer是一样的。

 

    那么,我们应该用回调,还是用仿函数?

    很多人都说用仿函数吧,回调函数是丑陋的,代码不太象C++风格。但其实问题的本质不是在代码风格上,仿函数与回调函数各有利弊,不能一概而论。

 

 

仿函数(functor)的优点

 

我的建议是,如果可以用仿函数实现,那么你应该用仿函数,而不要用回调。原因在于:

  • 仿函数可以不带痕迹地传递上下文参数。而回调技术通常使用一个额外的void*参数传递。这也是多数人认为回调技术丑陋的原因。
  • 更好的性能。

 

    仿函数技术可以获得更好的性能,这点直观来讲比较难以理解。你可能说,回调函数申明为inline了,怎么会性能比仿函数差?我们这里来分析下。我们假设某个函数func(例如上面的std::sort)调用中传递了一个回调函数(如上面的compare),那么可以分为两种情况:

  • func是内联函数,并且比较简单,func调用最终被展开了,那么其中对回调函数的调用也成为一普通函数调用(而不是通过函数指针的间接调用),并且如果这个回调函数如果简单,那么也可能同时被展开。在这种情形下,回调函数与仿函数性能相同。
  • func是非内联函数,或者比较复杂而无法展开(例如上面的std::sort,我们知道它是快速排序,函数因为存在递归而无法展开)。此时回调函数作为一个函数指针传入,其代码亦无法展开。而仿函数则不同。虽然func本身复杂不能展开,但是func函数中对仿函数的调用是编译器编译期间就可以确定并进行inline展开的。因此在这种情形下,仿函数比之于回调函数,有着更好的性能。并且,这种性能优势有时是一种无可比拟的优势(对于std::sort就是如此,因为元素比较的次数非常巨大,是否可以进行内联展开导致了一种雪崩效应)。

 

仿函数(functor)不能做的?

 

话又说回来了,仿函数并不能完全取代回调函数所有的应用场合。例如,我在std::AutoFreeAlloc中使用了回调函数,而不是仿函数,这是因为AutoFreeAlloc要容纳异质的析构函数,而不是只支持某一种类的析构。这和模板(template)不能处理在同一个容器中支持异质类型,是一个道理。

 

 

原文地址:http://blog.csdn.net/xushiweizh/article/details/1519828

 

分享到:
评论

相关推荐

    C++中回调函数(CallBack)的用法分析

    本文实例分析了C++中回调函数(CallBack)的用法。分享给大家供大家参考。具体分析如下: 如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过。 其错误是普通的C++成员函数都隐含了一个传递...

    JNI 回调函数 Callback

    综上所述,JNI回调函数Callback是Android开发中连接Java和C/C++的重要方式,它使得两个世界之间的通信更为灵活,能够实现更多复杂的逻辑。在实际应用中,开发者需要熟练掌握JNI的基础知识,并了解如何安全有效地使用...

    Qt使用回调函数方(callback)

    可能包含了具体的信号槽连接示例,而`mainwindow.ui`则是Qt Designer生成的用户界面文件,`callback.pro`和`callback.pro.user`则是项目配置文件,它们共同构成了一个关于Qt回调函数使用的实例项目。

    回调函数Callback_Function.doc

    尽管在C++中还有其他替代方案,如虚拟函数和函数对象,但回调函数仍然是许多系统和库的核心部分,尤其在需要与C代码交互或处理遗留接口时。理解和熟练使用回调函数是成为熟练程序员的关键技能之一。

    回调函数Callback Function.pdf

    在【标题】"回调函数Callback Function.pdf"中,主要讨论了回调函数的概念、使用场景以及简单的实现方式。在【描述】中虽然没有给出具体内容,但从标签"毕业设计 cs"可以看出,这是针对计算机科学(CS)领域,尤其是...

    回调函数Callback Function.docx

    然而,虽然回调函数在C++中是有用的,但在C++中更推荐使用虚函数或函数对象(functor)来替代回调函数,特别是在面向对象编程中,因为它们提供了更好的封装和类型安全。虚函数允许通过继承和多态性实现动态绑定,而...

    使用C语言写的回调函数

    - **定义回调函数类型**:首先,我们需要定义一个函数原型,表示回调函数的参数和返回值类型。例如: ```c typedef void (*CallbackType)(int data); // 定义一个接受整型参数并无返回值的回调函数类型 ``` - **声明...

    VC中回调函数(callback)深入解析

    VC 中回调函数(callback)深入解析 回调函数是计算机编程中的一种重要概念,它允许程序员在特定的时间点执行特定的函数,以响应某些事件的发生。下面是对 VC 中回调函数的深入解析。 什么是回调函数? ------------...

    PB 回调函数,多线程

    通过阅读和学习这些示例,开发者可以了解如何在自己的项目中应用PB回调函数和多线程技术。 总结来说,PB回调函数在多线程环境中的应用涉及到数据序列化、事件处理、线程安全以及组件化开发等多个方面。通过合理利用...

    halcon外触发get_framegrabber_callback注册回调函数方法

    - **Halcon API**:Halcon 提供给用户的编程接口,包括各种图像处理函数和设备控制函数。 #### 四、C# 示例代码详解 本节将详细解析给定的部分代码示例,以便更好地理解整个过程。 ##### 4.1 初始化与加载 ```...

    callback手把手教你写回调函数源代码

    通过以上步骤,你已经掌握了在Linux环境下编写回调函数和制作库文件的基本方法。在实际开发中,可以根据项目需求进行扩展和优化,比如添加错误处理、多线程支持等。希望这篇教程能帮助你更好地理解和运用这些技术。

    BCB线程中调用主界面的回调函数

    网上的回调函数都是API例子,学习函数指针倒是不错,可是很难让初学者立即应用。常见的情况是辅线程完成某事件后需要“通知”主界面,比如常见的进度条——线程中完成一定的进度后即通知主界面显示到一定的刻度。本...

    delphi Dll的回调函数

    总结起来,Delphi的DLL回调函数是实现模块化和通信的重要手段,通过传递函数指针,DLL可以将控制权交还给调用者,允许调用者在适当的时候处理结果或事件。这种技术在软件开发中有着广泛的应用,尤其是在需要高效、...

    Android回调函数的例子

    总结一下,回调函数是Java和Android开发中的核心概念,它们使我们能够以松耦合的方式处理事件和异步操作。通过理解并熟练运用回调函数,开发者可以构建更灵活、响应更快的应用程序。在实际项目中,要善于利用回调来...

    动态库回调函数示例

    在编程领域,动态链接库(Dynamic Link Library,简称 DLL)是一种可执行文件格式,它包含可供其他程序调用的函数和资源。DLL 文件允许多个应用程序共享同一代码库,从而节省内存并提高系统效率。VC++6.0 是 ...

    JQ Callback 回调函数

    在JavaScript的世界里,jQuery(简称JQ)是一个广泛使用的库,极大地简化了...理解和熟练运用回调函数是每个jQuery开发者必备的技能。在进行项目实践时,可以结合压缩包中的`demo`文件进行学习,进一步巩固这些概念。

    C++回调函数.pdf////C++回调函数.pdfC++回调函数.pdf

    通常,回调函数的原型会在调用者和被调用者之间共享。例如: ```cpp typedef int (__stdcall *CallbackFunc)(int, int); ``` 这里定义了一个名为`CallbackFunc`的函数指针类型,它接受两个`int`类型的参数,并...

    C# 实现回调函数

    回调函数通常用于异步编程,事件处理或者作为参数传递,使得代码更加灵活和可扩展。接下来,我们将深入探讨C#中实现回调函数的原理、方式以及应用场景。 首先,我们需要理解什么是回调函数。回调函数本质上就是一个...

    callback回调函数

    Callback回调函数作为一种重要的编程模式,在各种编程语言和框架中都有广泛的应用。理解和掌握回调函数的工作原理及使用方法对于提高程序设计能力具有重要意义。无论是进行事件处理、异步编程还是多线程编程,合理...

Global site tag (gtag.js) - Google Analytics