关于函数对象

rhesus 2003-11-04 10:15:08
到底用函数对象和函数指针有什么区别?
C++primer上说函数指针的缺点是他的间接应用使其不能被内联(不解其义)
...全文
446 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ntxs 2003-11-18
  • 打赏
  • 举报
回复
up
eastsun 2003-11-07
  • 打赏
  • 举报
回复


函数对象大约相当于数学中的算子。

而函数指针就是指向某函数的指针。

函数对象一般是将( )(其中可以不带参数或者带若干个参数)进行了重载。

FOR EXAMPLE。

class _functor
{
public:
_functor( );
virtual ~_functor( );

public:
double operator ( ) ( double dX );
};

void TestFunctor( )
{
_functor temp_functor;
double bValue = temp_functor( 3.0 );
}
Wolf0403 2003-11-05
  • 打赏
  • 举报
回复
Function几乎是任何语言的元素之一,从Pascal,Fortran到C++,VB,几乎任何时代的语言都支持它。在C++里,随着 C++标准库的推出,人们开始渐渐的接触到另一种定义函数的方式:Functor。所谓Functor,其实就是重载了operator () 的类,其使用方式和普通函数差不多(这正是C++处处体现的一种思想:只在定义上有区别,在使用上毫无区别)。
  譬如说,如果我们要定义一个函数,将传入的整型引用加一,我们可以有两种方法定义:
inline void increase_one_func(int& i)
{
  ++i;
}
class increase_one_functor
{
public:
  void operator()(int& i)
  {
    ++i;
  }
}
increase_one_functor;
使用起来则没什么区别:
int i=0;
increase_one_func(i);
increase_one_functor(i);

  那Function和Functor到底有什么区别呢?其实他们定义方式的区别已经决定了他们使用上的区别了。

  首先,Functor相比Function来说,可以传递更多的信息:
因为Functor是以类的方式存在的,它可以包含任意多的信息。除了传入参数以外,你还可以在类内预设一些其它的信息。
譬如说,下面这个Functor:
class increase_one_functor
{
  int mIncrement;
public:
  increase_one_functor(int increment=1):mIncrement(increment)
  {}
  void operator()(int& i)
  {
    ++i;
  }
}
  可以很方便的实现将一个整数增加任意值的功能:
increase_one_functor(100)(i);// 将i加100。
  而Function就很难实现这样的可扩展性。

  其次,在作为参数传递时,Functor的效率往往比Function要高。这是因为,在把Functor作为参数传递时,你实际上传递的是Functor对象,在整个编译过程中,编译器始终知道它所在处理的Functor对象是哪个Functor类的,也就是说,它可以做编译时的优化。而对于Function来说,它往往以指针的方式传递,对于编译器来说,很难做(并不是不可能)编译时的优化。
  下面这段程序或许可以说明问题:
#include <windows.h>
#include <iostream>

using namespace std;

inline void increase_one_func(int& i)
{
  ++i;
}

class increase_one_functor
{
public:
  void operator()(int& i)
  {
    ++i;
  }
}
increase_one_functor;

const int VECTOR_SIZE=1024*16;

void treat_vector_func(int ai[VECTOR_SIZE],void (*func)(int& i))
{
  for(int i=0;i<VECTOR_SIZE;++i)
    func(ai[i]);
}

template<typename T>
void treat_vector_func(int ai[VECTOR_SIZE],T functor)
{
  for(int i=0;i<VECTOR_SIZE;++i)
    functor(ai[i]);
}

void main(void)
{
  static int ai[VECTOR_SIZE];
  const int CALL_TIMES=10240;
  {
    long l=GetTickCount();
    for(int i=0;i<CALL_TIMES;++i)
      treat_vector_func(ai,increase_one_func);
    l=GetTickCount()-l;
    cerr<<"function "<<l<<endl;
  }
  {
    long l=GetTickCount();
    for(int i=0;i<CALL_TIMES;++i)
      treat_vector_func(ai,increase_one_functor);
    l=GetTickCount()-l;
    cerr<<"functor "<<l<<endl;
  }
}
  运行结果如下:
  Debug模式下(也就是说,没有任何优化的情况下):
function 37623
functor 36825
Release模式下:
function 4573
functor 1726
  可见,functor比function要快很多。


——以上转自 AllAboutProgramming 论坛
Robin 2003-11-05
  • 打赏
  • 举报
回复
挺复杂的,不是三言两语可以讲明白的!
Robin 2003-11-05
  • 打赏
  • 举报
回复
那是一种设计模式!用来降低对象之间的联系(decoupled interobject communication)!
是一种将请求(request)存储在对象之中的的设计思路!
参看《Modern C++ Designe Generic Prigamming and Design Patterns Applied》!
或者设计模式Command!
短歌如风 2003-11-05
  • 打赏
  • 举报
回复
“他的间接应用使其不能被内联”这样说是正确的——正如bosedom的解释——但这还并不能成为他的缺点——至少不是什么了不得的缺点。并且这种说法只适用于“泛型函数对象”而不适用于“多态函数对象”。

使用函数指针实现"callback"的最大缺点是它没有状态,而对象则可以有状态。
比如一个排序函数,如果它要求用一个参数传入比较函数, 如果我们用函数对象,我们就可以轻易写一个对比较次数进行统计的函数对象来对这个排序进行分析。而函数指针则不行。
当然,用函数指针可以用全局变量来存放状态,但这个状态并不是它的,而是全局的,因此,一旦你用了这种方法:
1:你的函数不是线程安全的。
2:你的函数是不可重入的。
3:不但不可重入,在被两个任务交叉调用都会得到你意想不到的结果。

当然,用函数指针也可以通过修改接口加入“自定义数据指针”的方法来实现自己的状态(大量需要回调的系统API和库函数如pthread_create都用了这种方法),但这种方法其实是“面向对象的C实现”,它用“自定义数据”和“函数指针”一起实现了一个“多态函数对象”。
C++primer我没有看过,如果只说了函数对象的这个优点或是对这个优点比较看重的话,颇有“买椟还珠”之嫌。
panzhaoping 2003-11-05
  • 打赏
  • 举报
回复
同意
bosedom 2003-11-04
  • 打赏
  • 举报
回复
函数对象实际上是一个类的对象,不过在使用的时候可以直接使用类名。
函数指针因为是用了指针,所以在编译的时候不能向内联函数那样在调用地直接展开。需要一定的开销。
chinajiji 2003-11-04
  • 打赏
  • 举报
回复
function pointer:
A pointer to a function, its' value is the function's address.

function object:
A object to be used as a function, function's states can be presented as the function object's members.

作为Microsoft 32位平台的应用程序编程接口, Win32 API是从事Windows应用程序开发所必备的。 首先对Win32 API函数做完整的概述;然后收录五大类函数: 窗口管理、图形设备接口、系统服务、国际特性以及网络服务; 在附录部分,讲解如何在Visual Basic和Delphi中对其调用。 本书是从事Windows应用程序开发的软件工程师的必备参考手册。 控件与消息函数 共91个函数 硬件与系统函数 共98个函数 设备场景函数 共73个函数 绘图函数 共105个函数 位图、图标和光栅运算函数 共39个函数 菜单函数 共37个函数 文本和字体函数 共41个函数 打印函数 共66个函数 文件处理函数 共118个函数 进程和线程函数 共40个函数 Windows消息函数 共11个函数 网络函数 共14个函数 目 录 第一章 Win32 API概论…………………………………………………………………………1 1.1 为什么使用Win32 API …………………………………………………………………1 1.2 Win32 API简介 …………………………………………………………………………1 1.3 综述………………………………………………………………………………………11 第二章 窗口管理函数(Windows Control Function) ……………………………………13 2.1 易用特性函数(Accessibility Features)…………………………………………13 2.2 按钮函数(Button)……………………………………………………………………20 2.3 插入标记(^)函数(Caret)…………………………………………………………21 2.4 组合框函数(Combo box) ……………………………………………………………24 2.5 通用对话框函数(Common Dialog Box) ……………………………………………25 2.6 标函数(Cursor)………………………………………………………………………36 2.7 对话框函数(Dialog Box)……………………………………………………………40 2.8 编辑控制函数(Edit Control)………………………………………………………54 2.9 图标函数(Icon)………………………………………………………………………54 2.10 键盘加速器函数(Keyboard Accelerator)……………………………………… 61 2.11 键盘输入函数(Keyboard InPut) …………………………………………………63 2.12 列表框函数(List box) ……………………………………………………………75 2.13 菜单函数(Menu) ……………………………………………………………………76 2.14 消息和消息队列函数(Message and Message Queue)……………………………90 2.15 鼠标输入函数(Mouse Input) ……………………………………………………100 2.16 多文档接口函数(Multiple Document Interface) ……………………………103 2.17 资源函数(Resource)………………………………………………………………105 2.18 滚动条函数(Scroll Bar)…………………………………………………………113 2.19 窗口函数(Window)…………………………………………………………………119 2.20 窗口类函数(Window Class)………………………………………………………144 2.21 窗口过程函数(Window Procedure)………………………………………………150 2.22 窗口属性函数(Window Property) ………………………………………………152 第三章 图形设备接口函数(Graphic Device Interface Function) …………………155 3.1 位图函数(Bitmap) …………………………………………………………………155 3.2 笔刷函数(Brush)……………………………………………………………………171 3.3 剪切函数(Clipping) ………………………………………………………………176 3.4 颜色函数(Color)……………………………………………………………………179 3.5 坐标空间与变换函数(Coordinate Space Transformation)……………………186 3.6 设备环境函数(Device Context) …………………………………………………195 3.7 填充形态函数(Filled shape) ……………………………………………………211 3.8 字体和正文函数(Font and Text)…………………………………………………215 3.9 ICM 2.0函数 …………………………………………………………………………238 3.10 线段和曲线函数(Line and Curve)………………………………………………295 3.11 图元文件函数(Metafile)…………………………………………………………300 3.12 多显示器函数(Multiple Display Monitors) …………………………………311 3.13 绘图函数和画图函数(Painting and Drawing)…………………………………313 3.14 路径函数(Path)……………………………………………………………………328 3.15 画笔函数(Pen) ……………………………………………………………………332 3.16 打印及打印假脱机程序函数(Printing and Print Spooler)…………………334 3.17 矩形函数(Rectangle) ……………………………………………………………371 3.18 区域函数(Region)…………………………………………………………………374 第四章 系统服务函数(System Service Function) ……………………………………383 4.1 访问控制函数(Access Control) …………………………………………………383 4.2 原子函数(Atom) ……………………………………………………………………406 4.3 客户/服务器访问控制函数(Client/Server Access Control) ………………409 4.4 剪贴板函数(Clipboard)……………………………………………………………431 4.5 通信函数(Communication)…………………………………………………………436 4.6 控制台函数(Console)………………………………………………………………444 4.7 数据解压库函数(Data Decompression Library) ………………………………463 4.8 调试函数(Debugging)………………………………………………………………466 4.9 设备输入输出函数(Device Input and Output)…………………………………472 4.10 动态数据交换函数(Dynamic Data Exchange) …………………………………474 4.11 动态数据交换管理函数(Dynamic Data Exchange Management)………………476 4.12 动态链接库函数(Dynamic-Link Library)………………………………………489 4.13 错误函数(Error) …………………………………………………………………496 4.14 事件日志函数(Event Logging) …………………………………………………499 4.15 文件函数(File)……………………………………………………………………503 4.16 文件安装库函数(File Installation Library) ………………………………542 4.17 文件映射函数(File Mapping)……………………………………………………546 4.18 文件系统函数 File System)………………………………………………………551 4.19 句柄和对象函数(Handle and Object)………………………………………………556 4.20 挂钩函数(Hook)………………………………………………………………………560 4.21 ImageHlp函数…………………………………………………………………………572 4.22 大整数操作函数(Iarge Integer Operations)……………………………………594 4.23 低层访问控制函数(Low-Level Access Control)………………………………596 4.24 LSAPI函数 …………………………………………………………………………617 4.25 邮槽函数(Mailslot)………………………………………………………………622 4.26 内存管理函数(Memory Management) ……………………………………………623 4.27 管道函数(Pipe) …………………………………………………………………655 4.28 电源管理函数(Power Management) …………………………………………… 663 4.29 进程和线程函数(Process and Thread)…………………………………………666 4.30 注册表函数(Registry)……………………………………………………………700 4.31 字符串操作函数(String Manipulation)……………………………………… 724 4.32 结构化异常处理函数(Structured Exception Handling) ……………………742 4.33 同步函数(Synchronization) ……………………………………………………745 4.34 系统信息函数(System Information)……………………………………………766 4.35 系统消息函数(System Message)…………………………………………………780 4.36 系统关机函数(System Shutdown) ………………………………………………781 4.37 磁带备份函数(Tape Backup) ……………………………………………………783 4.38 时间函数(Time)……………………………………………………………………789 4.39 计时器函数(Timer) ………………………………………………………………795 4.40 工具帮助函数(Tool Help) ………………………………………………………796 4.41 窗口站和桌面函数(Window Station and Desktop)……………………………799 4.42 Windows NT 4.0访问控制函数(Window NT 4.0 Access-Control)……………808 4.43 WinTrust函数(WinTrust)…………………………………………………………814 第五章 国际特性函数(International Peatures Punction)时性…………………………815 5.1 输入方法编辑函数(Input Method Editor)…………………………………………815 5.2 国家语言支持函数(National Language Support)………………………………… 828 5.3 Unicode和字符集函数(Unicode and Character Set)……………………………… 843 第六章 网络服务函数(Networding Service Function)……………………………………849 6.1 数据链路控制函数(DLC)………………………………………………………………849 6.2 网络函数(Net)…………………………………………………………………………849 6.3 NetBIOS函数……………………………………………………………………………896 6.4 网络DDE函数(Networking DDE)……………………………………………………897 6.5 RAS服务器管理函数(RAS Server Administration)………………………………901 6.6 远程访问服务函数(Remote Access Administration)………………………………910 6.7 服务函数(Service)……………………………………………………………………929 6.8 Windows网络函数(Windows Networking)……………………………………………930 附录1 如何在VB中调用DLL API ……………………………………………………………945 1 DLL API的声明……………………………………………………………………………945 2 DLL API的调用……………………………………………………………………………947 附录2 在Delphi中直接调用Windows API…………………………………………………953
JavaScript核心技术 简介: 《JavaScript核心技术》对于各种浏览器、浏览器版本、JavaScript版本、DOM版本的介绍,有助于我们理解所遇到的各种新旧代码,使我们能够对这些代码做出正确的取舍。《JavaScript核心技术》还提供了一些使用JavaScript的最佳实践。无论是新手还是老手,这些如何正确使用JavaScript的经验都能帮助他们养成良好的编程习惯。《JavaScript核心技术》还介绍了一些调试和开发JavaScript的工具,这些工具无疑能够提高我们的开发效率。 《JavaScript核心技术》最后对于Ajax和几个流行的JavaScript库的介绍,无疑会开阔我们在JavaScript使用上的思路。 《JavaScript核心技术》是一本真正意义上的“新书”,不仅介绍了最新的JavaScript知识和方向,还完全覆盖了当今Web开发中关于JavaScript的所有重要话题,它使用了大量实例代码,图文并茂地讲解了使用JavaScript的各个层次和领域的内容。它不是一本参考手册,但却是一本值得拥有的教程。 JavaScript核心技术 目录: 前言 第1章JavaScript初探 1.1规范和实现相互交织的历史 1.2跨浏览器的不兼容性和其他常见的JavaScript传说 1.3你能用JavaScript来做什么 1.4JavaScript初探:“HelloWorld!” 1.5JavaScript沙箱 1.6可访问性和JavaScript的最佳实践 第2章JavaScript数据类型与变量 2.1变量的标识 2.2作用域 2.3简单类型 2.4常量:有名称但不改变 2.5习题 第3章运算符和语句 3.1JavaScript语句的格式 3.2简单语句 3.3条件语句和程序流 3.4条件运算符 3.5逻辑运算符 3.6高级语句:循环语句 3.7习题 第4章JavaScript对象 4.1对象构造函数 4.2Number对象 4.3String对象 4.4正则表达式与RegExp 4.5有专门用途的对象:Date和Math 4.6JavaScript数组 4.7关联数组:不是数组的数组 4.8习题 第5章函数 5.1定义函数:细数所有方式 5.2回调函数 5.3函数和递归 5.4嵌套函数函数闭包和内存泄漏 5.5作为对象函数 5.6习题 第6章捕捉事件 6.1O级DOM上的事件句柄 6.22级DOM上的事件句柄 6.3产生事件 6.4习题 第7章表单与即时验证 7.1访问表单 7.2把事件附加在表单上:不同的方法 7.3选择列表 7.4单选按钮和复选框 7.5输入字段和JiT正则表达式 7.6习题 第8章沙箱及之上的cookie、连通性和隐私 第9章基础浏览器对象 第10章DOM:文档对象模型 第11章创建定制的JavaScript对象 第12章构建动态网页:在脚本中加入样式 第13章使用Ajax 第14章好消息:生动的程序库!令人惊异的Web服务!有趣的API! 附录习题答案

24,860

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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