C++中的函数指针与函数对象的总结

篇一、函数指针
函数指针:
是指向函数的指针变量,在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址。

函数指针的用途是很大的,主要有两个作用:用作调用函数和做函数的参数。

函数指针的声明方法:
数据类型标志符 (指针变量名) (形参列表);
一般函数的声明为:
int func ( int x );
而一个函数指针的声明方法为:
int (*func) (int x);
前面的那个(*func)中括号是必要的,这会告诉编译器我们声明的是函数指针而不是声明一个具有返回型为指针的函数,后面的形参要视这个函数指针所指向的函数形参而定。
然而这样声明我们有时觉得非常繁琐,于是typedef可以派上用场了,我们也可以这样声明:
typedef int (*PF) (int x);
PF pf;
这样pf便是一个函数指针,方便了许多。当要使用函数指针来调用函数时,func(x)或者  (*fucn)(x) 就可以了,当然,函数指针也可以指向被重载的函数,编译器会为我们区分这些重载的函数从而使函数指针指向正确的函数。
例子:


代码如下:

typedef void (*PFT) ( char ,int );
void bar(char ch, int i)
{
    cout<<"bar "<<ch<<' '<<i<<endl;
    return ;
}
PFT pft;
pft = bar;
pft('e',91);

例子中函数指针pft指向了一个已经声明的函数bar(),然后通过pft来实现输出字符和整型的目的。
函数指针另一个作用便是作为函数的参数,我们可以在一个函数的形参列表中传入一个函数指针,然后便可以在这个函数中使用这个函数指针所指向的函数,这样便可以使程序变得更加清晰和简洁,而且这种用途技巧可以帮助我们解决很多棘手的问题,使用很小的代价就可获得足够大的利益(速度+复杂度)。


代码如下:

typedef void (*PFT) ( char ,int );
void bar(char ch, int i)
{
    cout<<"bar "<<ch<<' '<<i<<endl;
    return ;
}
void foo(char ch, int i, PFT pf)
{
    pf(ch,i);
    return ;
}
PFT pft;
pft = bar;
foo('e',12,pft);

上述例子我们首先利用一个函数指针pft指向bar(),然后在foo()函数中使用pft指针来调用bar(),实现目的。将这个特点稍加利用,我们就可以构造出强大的程序,只需要同样的foo函数便可以实现对不同bar函数的调用。

篇二、函数对象
前面是函数指针的应用,从一般的函数回调意义上来说,函数对象和函数指针是相同的,但是函数对象却具有许多函数指针不具有的有点,函数对象使程序设计更加灵活,而且能够实现函数的内联(inline)调用,使整个程序实现性能加速。

函数对象:这里已经说明了这是一个对象,而且实际上只是这个对象具有的函数的某些功能,我们才称之为函数对象,意义很贴切,如果一个对象具有了某个函数的功能,我们变可以称之为函数对象。
如何使对象具有函数功能呢,很简单,只需要为这个对象的操作符()进行重载就可以了,如下:


代码如下:

class A{
public:
int operator()(int x){return x;}
};
A a;
a(5);

这样a就成为一个函数对象,当我们执行a(5)时,实际上就是利用了重载符号()。
函数对象既然是一个“类对象”,那么我们当然可以在函数形参列表中调用它,它完全可以取代函数指针!如果说指针是C的标志,类是C++特有的,那么我们也可以说指针函数和函数对象之间的关系也是同前者一样的!(虽然有些严密)。当我们想在形参列表中调用某个函数时,可以先声明一个具有这种函数功能的函数对象,然后在形参中使用这个对象,他所作的功能和函数指针所作的功能是相同的,而且更加安全。
下面是一个例子:


代码如下:

class Func{
public:
    int operator() (int a, int b)
    {
        cout<<a<<'+'<<b<<'='<<a+b<<endl;
        return a;
    }
};
int addFunc(int a, int b, Func& func)
{
    func(a,b);
    return a;
}
Func func;
addFunc(1,3,func);

上述例子中首先定义了一个函数对象类,并重载了()操作符,目的是使前两个参数相加并输出,然后在addFunc中的形参列表中使用这个类对象,从而实现两数相加的功能。
如果运用泛型思维来考虑,可以定一个函数模板类,来实现一般类型的数据的相加:


代码如下:

class FuncT{
public:
    template<typename T>
    T operator() (T t1, T t2)
    {
        cout<<t1<<'+'<<t2<<'='<<t1+t2<<endl;
        return t1;
    }
};
template <typename T>
T addFuncT(T t1, T t2, FuncT& funct)
{
    funct(t1,t2);
    return t1;
}
FuncT funct;
addFuncT(2,4,funct);
addFuncT(1.4,2.3,funct);

大名鼎鼎的STL中便广泛的运用了这项技术,详细内容可参见候捷大师的一些泛型技术的书籍,不要以为函数对象的频繁调用会使程序性能大大折扣,大量事实和实验证明,正确使用函数对象的程序要比其他程序性能快很多!所以掌握并熟练运用函数对象才能为我们的程序加分,否则.......
如此看来,函数对象又为C++敞开了一道天窗,但随之而来的便是一些复杂的问题和陷阱,如何去蔽扬利还需要我们不断学习和探索。

(0)

相关推荐

  • C++基础入门教程(八):函数指针

    最近事情比较多,其实并不忙,就是事情比较影响思绪,所以都没心思写文章了. 今天主要说说函数的一些基本情况吧,同时也解释一下新手最容易迷糊的--什么时候要用指针参数? 一.函数原型和函数定义 大家都知道,C++定义函数之前,还需要声明函数原型,对于习惯Java等其他高级语言的朋友来说,真心觉得这很烦人. 如下代码: 复制代码 代码如下: // 声明函数原型 void startGame(int param); // 函数定义 void startGame(int param) {     // 各

  • C++获取类的成员函数的函数指针详解及实例代码

    C++获取类的成员函数的函数指针详解 用一个实际代码来说明. class A { public: staticvoid staticmember(){cout<<"static"<<endl;} //static member void nonstatic(){cout<<"nonstatic"<<endl;} //nonstatic member virtualvoid virtualmember(){cout<

  • c++函数指针使用示例分享

    需求假设要设计一个名为estimate()的函数,估算编写指定行数的代码所需的时间,并且希望不同的程序员都可以使用该函数. 对于所有的用户来说,estimate()中一部分代码都是相同的,但该函数允许每个程序员提供自己的算法来估算时间. 为实现目标,采用的机制是,将程序员要使用的算法函数的地址传递给estimate(). 实现代码如下 复制代码 代码如下: // funpointer.cpp : 定义控制台应用程序的入口点.//#include "stdafx.h"#include &

  • C++普通函数指针与成员函数指针实例解析

    C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般函数的函数指针使用的比较多,而对指向类成员函数的函数指针则比较陌生.本文即对C++普通函数指针与成员函数指针进行实例解析. 一.普通函数指针 通常我们所说的函数指针指的是指向一般普通函数的指针.和其他指针一样,函数指针指向某种特定类型,所有被同一指针运用的函数必须具有相同的形参类型和返回类型. int (*pf)(int, int); // 声明函数指针 这里,pf指向的函数类型是int (

  • c++传递函数指针和bind的示例

    复制代码 代码如下: #include <algorithm>class TestClass{public: int Sub(int x, int y) {  return y - x; } void InitAndTest() {  PrintWithClassMemberFunction(&TestClass::Sub);  PrintWithClassPointer(this); } // call: PrintWithClassMemberFunction(&TestC

  • c++回调之利用函数指针示例

    c++回调之利用函数指针示例 复制代码 代码如下: #include <iostream>using namespace std; /************************************************************************//*                下层实现: CALLBACK                                        *//**********************************

  • 详解C++中的指针、数组指针与函数指针

    C++中一个重要的特性就是指针,指针不仅具有获得地址的能力,还具有操作地址的能力.指针可以用于数组.或作为函数的参数,用来访问内存和对内存的操作,指针的使用使得C++很高效,但是指针也非常危险,使用不当会带来比较严重的问题. 1.指针 程序中所有的变量和常量都存在一个内存地址中,当然,函数也有对应的内存地址,内存地址的不同会导致程序执行时有所不同. 指针就是用来控制和存储内存地址的变量,它指向单个对象的地址,除了void之外,指针的数据类型与所指向地址的变量数据类型保持一致. 2.如何定义指针.

  • c++函数指针和回调函数示例

    1.函数指针 函数指针是一个指针,只是这个指针它不像普通的指针指向是是一个变量,此时它指向的是一个函数,也就是它存储的是一个函数的地址,如果我们改变它的值,让它所指向的地址由指向funA转变为指向funB,那么这个函数指针的作用就改变了. 2.回调函数 什么是回调函数呢?回调函数其实就是一个通过函数指针调用的函数!假如你把A函数的指针当作参数传给B函数,然后在B函数中通过A函数传进来的这个指针调用A函数,这就是回调机制.B函数就是回调函数. 3.函数指针的使用 3.1函数指针声明 typedef

  • 详解C语言编程中的函数指针以及函数回调

    函数指针: 就是存储函数地址的指针,就是指向函数的指针,就是指针存储的值是函数地址,我们可以通过指针可以调用函数. 我们先来定义一个简单的函数: //定义这样一个函数 void easyFunc() { printf("I'm a easy Function\n"); } //声明一个函数 void easyFunc(); //调用函数 easyFunc(); //定义这样一个函数 void easyFunc() { printf("I'm a easy Function\n

  • C++中的函数指针与函数对象的总结

    篇一.函数指针函数指针:是指向函数的指针变量,在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址. 函数指针的用途是很大的,主要有两个作用:用作调用函数和做函数的参数. 函数指针的声明方法:数据类型标志符 (指针变量名) (形参列表):一般函数的声明为: int func ( int x );而一个函数指针的声明方法为:int (*func) (int x);前面的那个(*func)中括号是必要的,这会告诉编译器我们声明的是函数指针而不是声明一个具有返回型为指针

  • 一起来学习C++的函数指针和函数对象

    目录 函数指针 函数对象 总结 函数指针 以下是<cstdlib>库中的一个排序数组的方法qsort()的函数原型. void qsort (void* base, size_t num, size_t size, int (*compar)(const void*, const void*)); base -- 指向要排序的数组的第一个元素的指针. num -- 由 base 指向的数组中元素的个数. size -- 数组中每个元素的大小,以字节为单位. compar -- 用来比较两个元素

  • c语言中的二级指针做函数参数说明

    目录 二级指针做函数参数 二级指针作为形参简单实例分析 实例 一级指针二级指针做函数形参 下面看看实例 二级指针做函数参数 1.用指针做函数参数申请动态内存的问题 //如果函数参数是指针,不能用一级指针做函数参数实现申请动态内存   void getMemory(char *p, int num) {     p = (char *)malloc(sizeof(char)*num); } void main() {     char *str = NULL;     getMemory(str,

  • 详解C++中的this指针与常对象

    C++ this指针详解 this 是C++中的一个关键字,也是一个常量指针,指向当前对象(具体说是当前对象的首地址).通过 this,可以访问当前对象的成员变量和成员函数. 所谓当前对象,就是正在使用的对象,例如对于stu.say();,stu 就是当前对象,系统正在访问 stu 的成员函数 say(). 假设 this 指向 stu 对象,那么下面的语句中,this 就和 pStu 的值相同: Student stu; //通过Student类来创建对象 Student *pStu = &s

  • 如何通过函数指针调用函数(实现代码)

    说明:指针可以不但可以指向一个整形,浮点型,字符型,字符串型的变量,也可以指向相应的数组,而且还可以指向一个函数. 一个函数在编译的时候会被分配给一个入口地址.这个函数入口地址称为函数的指针.可以用一个指针变量指向函数,然后通过该指针变量调用此函数. 定义指向函数的指针变量的方法是: 复制代码 代码如下: int (*p) (int ,int ); int[指针变量p指向的函数的类型] (*p)[p是指向函数的指针变量] ( int,int )[p所指向的形参类型]; 与函数的原型进行比较 复制

  • C++中函数指针详解及代码分享

    函数指针 函数存放在内存的代码区域内,它们同样有地址.如果我们有一个int test(int a)的函数,那么,它的地址就是函数的名字,如同数组的名字就是数组的起始地址. 1.函数指针的定义方式:data_types (*func_pointer)( data_types arg1, data_types arg2, ...,data_types argn); c语言函数指针的定义形式:返回类型 (*函数指针名称)(参数类型,参数类型,参数类型,-); c++函数指针的定义形式:返回类型 (类名

  • C语言中函数指针与软件设计经验总结

    函数指针与软件设计 记得刚开始工作时,一位高手告诉我,说,longjmp和setjmp玩得不熟,就不要自称为C语言高手.当时我半信半疑,为了让自己向高手方向迈进,还是花了一点时间去学习longjmp和setjmp的用法.后来明白那不单是跳来跳去那样简单,而是一种高级的异常处理机制,在某些情况下确实很有用. 为了显示自己的技巧,也在自己的程序中用过几次.渐渐发现这样的技巧带来的好处是有代价的,破坏了程序的结构化设计,程序变得很难读,尤其对新手来说.终于明白这种技巧不过是一种调味料,在少数情况使用几

  • C++函数指针+对象指针+this指针+指向类静态和非静态成员的指针

    目录 1.指向函数的指针 2.对象指针 3.this指针 4.指向类的非静态成员的指针 5.指向类的静态成员的指针 1.指向函数的指针 函数的代码在内存中的首地址,是由函数名表示的,也就是说函数名等价于函数代码首地址.因此,可以定义一个指向函数的指针,即函数指针.函数指针定义和赋值的语法如下,其中数据类型代表指向函数的返回类型,形参表为指向函数的形参表:赋值时必须保证指向的函数名和函数指针的返回类型和形参完全相同: 数据类型 (*函数指针名)(形参表);函数指针名 = 函数名; 下面的例子定义了

随机推荐