社区
工具平台和程序库
帖子详情
关于函数对象
rhesus
2003-11-04 10:15:08
到底用函数对象和函数指针有什么区别?
C++primer上说函数指针的缺点是他的间接应用使其不能被内联(不解其义)
...全文
439
9
打赏
收藏
关于函数对象
到底用函数对象和函数指针有什么区别? C++primer上说函数指针的缺点是他的间接应用使其不能被内联(不解其义)
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用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.
(推荐)Win32 API大全
4.19 句柄和
对象
函数
(Handle and Object)………………………………………………556 4.20 挂钩
函数
(Hook)………………………………………………………………………560 4.21 ImageHlp
函数
…………………………...
python简明教程.chm
对象
与类的快速入门 使用列表 元组 使用元组 元组与打印语句 字典 使用字典 序列 使用序列 参考
对象
与参考 更多字符串的内容 字符串的方法 概括 10. 解决问题——编写一个Python脚本 问题 ...
JavaScript核心技术 PDF扫描版
4.1
对象
构造
函数
4.2Number
对象
4.3String
对象
4.4正则表达式与RegExp 4.5有专门用途的
对象
:Date和Math 4.6JavaScript数组 4.7关联数组:不是数组的数组 4.8习题 第5章
函数
5.1定义
函数
:细数所有方式 5.2回调
函数
...
腾讯2012笔试题目
此题涉及一个基类`CBase`和一个派生类`CSub`,在`main`
函数
中创建了`CSub`类型的
对象
。需要判断构造
函数
与析构
函数
的执行顺序。 - **选项分析:** - A: 先输出子类构造
函数
,再输出基类构造
函数
,这不符合C++的...
叙述讲解C++编程
全书共分十八章,内容涉及
对象
的演化、数据抽象、隐藏实现、初始化与清除、
函数
重载与缺省参数、输入输出流介绍、常量、内联
函数
、命名控制、引用和拷贝构造
函数
、运算符重载、动态
对象
创建、继承和组合、多态和虚...
工具平台和程序库
24,860
社区成员
27,340
社区内容
发帖
与我相关
我的任务
工具平台和程序库
C/C++ 工具平台和程序库
复制链接
扫一扫
分享
社区描述
C/C++ 工具平台和程序库
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章