一 函数指针介绍


函数指针指向某种特定类型,函数的类型由其参数及返回类型共同决定,与函数名无关。举例如下:

  1. int add(int nLeft,int nRight);//函数定义

该函数类型为int(int,int),要想声明一个指向该类函数的指针,只需用指针替换函数名即可

  1. int (*pf)(int,int);//未初始化

则pf可指向int(int,int)类型的函数。pf前面有*,说明pf是指针,右侧是形参列表,表示pf指向的是函数,左侧为int,说明pf指向的函数返回值为int。则pf可指向int(int,int)类型的函数。而add类型为int(int,int),则pf可指向add函数。

  1. pf = add;//通过赋值使得函数指针指向某具体函数

注意:*pf两端的括号必不可少,否则若为如下定义:

  1. int *pf(int,int);//此时pf是一个返回值为int*的函数,而非函数指针

二 标准C函数指针


 1函数指针的定义

1.1 普通函数指针定义

  1. int (*pf)(int,int);

1.2 使用typedef定义函数指针类型

  1. typedef int (*PF)(int,int);
  2. PF pf;//此时,为指向某种类型函数的函数指针类型,而不是具体指针,用它可定义具体指针</span>

 2函数指针的普通使用

  1. pf = add;
  2. pf(100,100);//与其指向的函数用法无异
  3. (*pf)(100,100);//此处*pf两端括号必不可少

注意:add类型必须与pf可指向的函数类型完全匹配

 3函数指针作为形参

  1. //第二个形参为函数类型,会自动转换为指向此类函数的指针
  2. Void fuc(int nValue,int pf(int,int));
  3. //等价的声明,显示的将形参定义为指向函数的指针
  4. Void fuc(int nValue,int (*pf)(int,int));
  5. Void fuc(int nValue,PF);

形参中有函数指针的函数调用,以fuc为例:

  1. pf = add;//pf是函数指针
  2. fuc(1,add);//add自动转换为函数指针
  3. fuc(1,pf);

 4返回指向函数的指针

4.1 使用typedef定义的函数指针类型作为返回参数

  1. PF fuc2(int);//PF为函数指针类型

4.2 直接定义函数指针作为返回参数

  1. int (*fuc2(int))(int,int);//显示定义

 说明:按照有内向外的顺序阅读此声明语句。fuc2有形参列表,则fuc2是一个函数,其形参为fuc2(int),fuc2前面有*,所以fuc2返回一个指针,指针本身也包含形参列表(int,int),因此指针指向函数,该函数的返回值为int.

总结:fuc2是一个函数,形参为(int),返回一个指向int(int,int)的函数指针。


二 C++函数指针


 1由于C++完全兼容C,则C中可用的函数指针用法皆可用于C++


2 C++其他函数(指针)定义方式及使用


2.1 typedef与decltype组合定义函数类型

  1. typedef decltype(add) add2;

decltype返回函数类型,add2是与add相同类型的函数,不同的是add2是类型,而非具体函数。

使用方法:

  1. add2* pf;//pf指向add类型的函数指针,未初始化

2.2 typedef与decltype组合定义函数指针类型

  1. typedef decltype(add)* PF2;//PF2与1.1PF意义相同
  1. PF2 pf;// pf指向int(int,int)类型的函数指针,未初始化

2.3 使用推断类型关键字auto定义函数类型和函数指针

  1. auto pf = add;//pf可认为是add的别名(个人理解)
  2. auto *pf = add;//pf为指向add的指针

3函数指针形参

  1. typedef decltype(add) add2;
  2. typedef decltype(add)* PF2;
  3. void fuc2 (add2 add);//函数类型形参,调用自动转换为函数指针
  4. void fuc2 (PF2 add);//函数指针类型形参,传入对应函数(指针)即可

说明:不论形参声明的是函数类型:void fuc2 (add2 add);还是函数指针类型void
fuc2 (PF2 add);都可作为函数指针形参声明,在参数传入时,若传入函数名,则将其自动转换为函数指针。

4  返回指向函数的指针

4.1 使用auto关键字

 auto fuc2(int)-> int(*)(int,int) //fuc2返回函数指针为int(*)(int,int) 

4.2 使用decltype关键字

  1. decltype(add)* fuc2(int)//明确知道返回哪个函数,可用decltype关键字推断其函数类型,

5 成员函数指针

5.1普通成员函数指针使用举例

  1. class A//定义类A
  2. {
  3. private:
  4. int add(int nLeft, int nRight)
  5. {
  6. return (nLeft + nRight);
  7. }
  8. public:
  9. void fuc()
  10. {
  11. printf("Hello  world\n");
  12. }
  13. };
  14. typedef void(A::*PF1)();//指针名前需加上类名限定
  15. PF1 pf1 = &A::fuc; //必须有&
  16. A a;//成员函数地址解引用必须附驻与某个对象地址,所以必须创建一个队形
  17. (a.*pf1)();//使用成员函数指针调用函数

5.2继承中的函数指针使用举例

  1. class A
  2. {
  3. public:
  4. void fuc()
  5. {
  6. printf("Hello fuc()\n");
  7. }
  8. void fuc2()
  9. {
  10. printf("Hello A::fuc2()\n");
  11. }
  12. };
  13. class B:public A
  14. {
  15. public:
  16. virtual void fuc2()
  17. {
  18. printf("Hello B::fuc2()\n");
  19. }
  20. };
  21. typedef void(A::*PF1)();
  22. typedef void(B::*PF2)();
  23. PF1 pf1 = &A::fuc;
  24. int main()
  25. {
  26. A a;
  27. B b;
  28. (a.*pf1)();  //调用A::fuc
  29. (b.*pf1)();   //调用A::fuc
  30. pf1 = &A::fuc2;
  31. (a.*pf1)();  //调用A::fuc2
  32. (b.*pf1)();  //调用A::fuc2
  33. PF2 pf2 = &A::fuc2;
  34. (b.*pf2)(); //调用A::fuc2
  35. }

6重载函数的指针

6.1 重载函数fuc

  1. Void fuc();
  2. Void fuc(int);

6.2 重载函数的函数指针

  1. void (*PF)(int) = fuc;//PF指向fuc(int)
  2. int(*pf2)(int) = fuc;//错误没有匹配的类型

注意:编译器通过指针类型决定选取那个函数,指针类型必须与重载函数中的一个精确匹配。

C/C++ 函数指针使用总结的更多相关文章

  1. C++虚函数和函数指针一起使用

    C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...

  2. 为什么 C++ 中成员函数指针是 16 字节?

    当我们讨论指针时,通常假设它是一种可以用 void * 指针来表示的东西,在 x86_64 平台下是 8 个字节大小.例如,下面是来自 维基百科中关于 x86_64 的文章 的摘录: Pushes a ...

  3. C++函数指针总结

    学习c++的过程中,指针是难点,熟悉了指针之后,还有一个让人很蛋疼的难点,那就是函数指针了.本博文详细介绍一下常见的各种坑爹的函数指针. 至于指针的详细学习,推荐这篇博文C++指针详解 与数据一样,函 ...

  4. C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用

    类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...

  5. 结构体内嵌函数指针实现C语言面向对象

    结构体内嵌函数指针 #include<stdio.h> void say(int age) { printf("我%d岁了\n",age); } struct stud ...

  6. 用typedef定义函数指针的问题

    在学习windows API的时候,遇到下面这段代码   以前见过的typedef的用法都是给一个数据类型取一个别名 typedef oldTypeName newTypeName   这种给数据类型 ...

  7. 你必须知道的指针基础-7.void指针与函数指针

    一.不能动的“地址”—void指针 1.1 void指针初探 void *表示一个“不知道类型”的指针,也就不知道从这个指针地址开始多少字节为一个数据.和用int表示指针异曲同工,只是更明确是“指针” ...

  8. objective-c中的@selector()和 c /c++的函数指针

    先看tomcat里用到的代码: //然后开始动画 //把图片放到animationImages,接受数组参数 self.tom.animationImages = arrayImage; //设置时间 ...

  9. C++基础——函数指针 函数指针数组

    ==================================声明================================== 本文版权归作者所有. 本文原创,转载必须在正文中显要地注明 ...

  10. QT中使用函数指针

    想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*com ...

随机推荐

  1. [LeetCode] 16. 最接近的三数之和

    题目链接:https://leetcode-cn.com/problems/3sum-closest/ 题目描述: 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 num ...

  2. Linux内存管理 (15)页面迁移

    专题:Linux内存管理专题 关键词:RMAP.页面迁移. 相关章节:反向映射RMAP.内存规整. 页面迁移的初衷是为NUMA系统提供一种将进程迁移到任意内存节点的能力,后来内存规整和内存热插拔场景都 ...

  3. springboot项目利用Swagger2生成在线接口文档

    Swagger简介. Swagger2是一款restful接口文档在线生成和在线调试工具.很多项目团队利用Swagger自动生成接口文档,保证接口文档和代码同步更新.在线调试.简单地说,你可以利用这个 ...

  4. 2019年美国大学生数学建模竞赛(MCM/ICM) E题解题思路

    这也许是我大学生涯最后一次参加数学建模比赛了吧,这次我们选择的问题是E题,以下是我们解题时候的一些思路.很多不易体现的项目产生对环境造成影响的指标可以由一些等同类型的指标来代替,如土地.森林植被被破环 ...

  5. 爬虫基础(一)-----request模块的使用

    ---------------------------------------------------摆脱穷人思维 <一>  :   建立时间价值的概念,减少做那些"时间花的多收 ...

  6. 阿里云对象存储OSS与文件存储NAS的区别

    一.简介 应用场景:选择一款存储产品,面向文档数据的存取,不会涉及到数据处理. 产品选型主要从OSS和NAS中选择一款,满足文档存储的需求. 二.NAS优缺点 NAS 是一种采用直接与网络介质相连的特 ...

  7. php_network_getaddresses: getaddrinfo failed 原因

    一般在调用外部服务请求时候,有时由于配置问题无法访问,phph会报一个php_network_getaddresses: getaddrinfo failed: Name or servicenot ...

  8. P2613 有理数取余

    原题链接 https://www.luogu.org/problemnew/show/P2613 在这里虽然是讲洛谷的题解,但用到的数论知识,归并到数论里也不为过! 进入正题: 首先看到题面:给出一个 ...

  9. CSS实现动画特效导航栏

    0 写在前面 今天用纯CSS编写了一种带有特效的导航栏,一方面巩固熟悉了导航栏的一般写法,另一方面练习了CSS3的一些新特性. 1 实现效果 当鼠标划过时,实现了一种动态百叶窗效果. 2 实现细节 2 ...

  10. Mybatis的应用1 Mybatis和logback的应用配置

    首先新建一个module, 然后,在pom文件里面添加一些引用的项. pom.xml <?xml version="1.0" encoding="UTF-8&quo ...