函数指针是指指向函数而非指向对象的指针。像其他指针一样,函数指针也指向某个特定的类型。函数类型由其返回类型以及形参表确定,而与函数名无关

// pf points to function returning bool that takes two const string references
bool (*pf)(const string &, const string &);

这个语句将 pf 声明为指向函数的指针,它所指向的函数带有两个 const string& 类型的形参和 bool 类型的返回值

*pf 两侧的圆括号是必需的:

// declares a function named pf that returns a bool*
bool *pf(const string &, const string &);

用typedef简化函数指针的定义。函数指针类型相当地冗长。使用 typedef 为指针类型定义同义词,可将函数指针的使用大大简化:

typedef bool (*cmpFcn)(const string &, const string &);

该定义表示 cmpFcn 是一种指向函数的指针类型的名字。该指针类型为“指向返回 bool 类型并带有两个 const string 引用形参的函数的指针”。在要使用这种函数指针类型时,只需直接使用 cmpFcn 即可,不必每次都把整个类型声明全部写出来。

  • 指向函数的指针的初始化和赋值

在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针。假设有函数:

// compares lengths of two strings
bool lengthCompare(const string &, const string &);

除了用作函数调用的左操作数以外,对 lengthCompare 的任何使用都被解释为如下类型的指针

bool (*)(const string &, const string &);

可使用函数名对函数指针做初始化或赋值

cmpFcn pf1 = ;             // ok: unbound pointer to function
cmpFcn pf2 = lengthCompare; // ok: pointer type matches function's type
pf1 = lengthCompare; // ok: pointer type matches function's type
pf2 = pf1; // ok: pointer types match

此时,直接引用函数名等效于在函数名上应用取地址操作符:

cmpFcn pf1 = lengthCompare;
cmpFcn pf2 = &lengthCompare;

函数指针只能通过同类型的函数或函数指针或 0 值常量表达式进行初始化或赋值。将函数指针初始化为 0,表示该指针不指向任何函数。指向不同函数类型的指针之间不存在转换

  • 通过指针调用函数

指向函数的指针可用于调用它所指向的函数。可以不需要使用解引用操作符,直接通过指针调用函数

cmpFcn pf = lengthCompare;
lengthCompare("hi", "bye"); // direct call
pf("hi", "bye"); // equivalent call: pf1 implicitly dereferenced
(*pf)("hi", "bye"); // equivalent call: pf1 explicitly dereferenced

如果指向函数的指针没有初始化,或者具有 0 值,则该指针不能在函数调用中使用。只有当指针已经初始化,或被赋值为指向某个函数,方能安全地用来调用函数。

  • 函数指针形参
/* useBigger function's third parameter is a pointer to function
* that function returns a bool and takes two const string references
* two ways to specify that parameter:
*/
// third parameter is a function type and is automatically treated as a pointer to
function
void useBigger(const string &, const string &,
bool(const string &, const string &));
// equivalent declaration: explicitly define the parameter as a pointer to function
void useBigger(const string &, const string &,
bool (*)(const string &, const string &));
  • 返回指针函数的指针

函数可以返回指向函数的指针,但是,正确写出这种返回类型相当不容易

// ff is a function taking an int and returning a function pointer
// the function pointed to returns an int and takes an int* and an int
int (*ff(int))(int*, int);

阅读函数指针声明的最佳方法是从声明的名字开始由里而外理解

要理解该声明的含义,首先观察:

ff(int)

ff 声明为一个函数,它带有一个 int 型的形参。该函数返回

int (*)(int*, int);

它是一个指向函数的指针,所指向的函数返回 int 型并带有两个分别是 int* 型和 int 型的形参。

使用 typedef 可使该定义更简明易懂

// PF is a pointer to a function returning an int, taking an int* and an int
typedef int (*PF)(int*, int);
PF ff(int); // ff returns a pointer to function

允许将形参定义为函数类型;函数的返回类型则必须是指向函数的指针,而不能是函数

具有函数类型的形参所对应的实参将被自动转换为指向相应函数类型的指针。但是,当返回的是函数时,同样的转换操作则无法实现:

// func is a function type, not a pointer to function!
typedef int func(int*, int);
void f1(func); // ok: f1 has a parameter of function type
func f2(int); // error: f2 has a return type of function type
func *f3(int); // ok: f3 returns a pointer to function type
  • 指向重载函数的指针

C++ 语言允许使用函数指针指向重载的函数:

extern void ff(vector<double>);
extern void ff(unsigned int); // which function does pf1 refer to?
void (*pf1)(unsigned int) = &ff; // ff(unsigned)

指针的类型必须与重载函数的一个版本精确匹配。如果没有精确匹配的函数,则对该指针的初始化或赋值都将导致编译错误:

// error: no match: invalid parameter list
void (*pf2)(int) = &ff; // error: no match: invalid return type
double (*pf3)(vector<double>);
pf3 = &ff;

《C++ Primer》之指向函数的指针的更多相关文章

  1. C++ —— 返回数组指针的函数 和 返回指向函数的指针的函数

    返回数组指针的函数 基础知识:数组不能被拷贝,函数不能返回数组,只能返回数组的指针或者引用. 定义一个 返回数组指针的函数 的方法,以 一个接收参数为 含有10个整型元素的数组的引用  和 返回一个含 ...

  2. C语言中 指向函数的指针 简介

    引子:在学习CPrimerPlus的第十四章的14.13节中,遇到了如下三行文字,是有关指向函数的指针的,把我搞晕了. char * fump(); //返回指向char的指针的函数 char (* ...

  3. 12-返回指针的函数&&指向函数的指针

    前言 接下来我只讲指针的最常见用法,比如这一章的内容----返回指针的函数 与 指向函数的指针   一.返回指针的函数 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的. 返回 ...

  4. 【C语言】14-返回指针的函数与指向函数的指针

    前言 前面我们花了接近3个章节学习指针,应该都感受到指针的强大了吧.指针可以根据地址直接操作内存中的数据,使用得当的话,不仅能使代码量变少,还能优化内存管理.提升程序性能.关于指针的内容还非常多,比如 ...

  5. 指向函数的指针与iOS-Block相关知识

    指向函数的指针与iOS-Block相关知识 一. 函数指针的定义和调用: 关于函数指针的知识详细可参考:http://www.cnblogs.com/mjios/archive/2013/03/19/ ...

  6. 指向函数的指针数组(C++)

    我们能够创建一个指向函数的指针数组.为了选择一个函数,只需要使用数组的下标,然后间接引用这个指针.这种方式支持表格式驱动码的概念:可以根据状态变量去选择被执行函数,而不用条件语句或case语句.这种设 ...

  7. 【学习笔记】【C语言】指向函数的指针

    每个函数都有自己的内存地址,指针保存了函数的地址后就能指向函数了. #include <stdio.h> double haha(double d, char *s, int a) { } ...

  8. C++学习笔记:指向函数的指针

    #include <stdio.h> int sum(int a, int b) { return a+b; } int minus(int a, int b) { return a-b; ...

  9. 指向函数的指针 分类: C/C++ 2015-07-13 11:03 14人阅读 评论(0) 收藏

    原文网址:http://www.cnblogs.com/zxl2431/archive/2011/03/25/1995285.html 讲的很清楚,备份记录. (一) 用函数指针变量调用函数 可以用指 ...

随机推荐

  1. 用Karma和Jasmine测试Angular应用

    TEST: Before you've written any of the code, you know how you want it to behave. You have a specific ...

  2. react总结

    在我的工作用到的最多就是backbone,其次还会有ember/Ext,backbone目前能实现我们team所需要实现的功能,因为我们的component不需要频繁的操作Dom,当后台API返回数据 ...

  3. linux 目录及文件的命名规则、ls操作

    linux 命名: 1 不超过255个字符 2 严格区分大小写 3 除/外,其他的字符都是合法的 注意:1)避免文件名首字符使用+ - .(避免和隐藏文件混淆) 2)避免文件名使用空格,制表符以及@# ...

  4. Mybatis的失误填坑-java.lang.Integer cannot be cast to java.lang.String

    Mybatis的CRUD小Demo 为方便查看每次的增删改结果,封装了查询,用来显示数据库的记录: public static void showInfo(){ SqlSession session ...

  5. Struts2第四天

    Struts2第四天 昨天: 自定义的拦截器:继续methodFilterInterceptor,可以指定哪些方法需要拦截或者不拦截. Intercepters(配置拦截器),intercepter( ...

  6. 第八十四节,css布局小技巧及font-awesome图标使用

    css布局小技巧及font-awesome图标使用 图片鼠标放上去遮罩效果,显示文字 当鼠标放上去时 /*最外层div*/ .a{ width: 384px; height: 240px; backg ...

  7. Java Lambda表达式入门[转]

    原文链接: Start Using Java Lambda Expressions http://blog.csdn.net/renfufei/article/details/24600507 下载示 ...

  8. 轻量级的移动框架--zepto.js

    Zepto是一个轻量级的支持移动WebKit浏览器javascript移动端框架,框架支持jQuery语法,该框架的压缩包zepto.min.js 大小只有21K, 使用服务器端 gzip 压缩后大小 ...

  9. 4、Math对象

    1.编辑html页面 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// ...

  10. [ An Ac a Day ^_^ ] hdu 1003 dp

    超时还有可能是数组开小了…… #include<stdio.h> #include<iostream> #include<algorithm> #include&l ...