C++函数指针使用总结

一 函数指针介绍

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

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

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

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

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

int(int,int),则pf可指向add函数。
pf = add;//通过赋值使得函数指针指向某具体函数  

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

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

二 标准C函数指针

1 函数指针的定义

1.1 普通函数指针定义
int (*pf)(int,int);  
1.2 使用typedef定义函数指针类型
typedef int (*PF)(int,int);  
PF pf; //此时,为指向某种类型函数的函数指针类型,而不是具体指针,用它可定义具体指针

2 函数指针的普通使用

pf = add;  
pf(100,100);//与其指向的函数用法无异  
(*pf)(100,100);//此处*pf两端括号必不可少  
注意:add类型必须与pf可指向的函数类型完全匹配

3 函数指针作为形参

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

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

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

4返回指向函数的指针

4.1 使用typedef定义的函数指针类型作为返回参数
PF fuc2(int);//PF为函数指针类型  
4.2 直接定义函数指针作为返回参数
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组合定义函数类型
typedef decltype(add) add2;  

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

使用方法:

add2* pf;//pf指向add类型的函数指针,未初始化  
2.2 typedef与decltype组合定义函数指针类型
typedef decltype(add)* PF2;//PF2与1.1PF意义相同  
PF2 pf;// pf指向int(int,int)类型的函数指针,未初始化  
2.3 使用推断类型关键字auto定义函数类型和函数指针
auto pf = add;//pf可认为是add的别名(个人理解)   
auto *pf = add;//pf为指向add的指针   

3 函数指针形参

typedef decltype(add) add2;  
typedef decltype(add)* PF2;  
void fuc2 (add2 add);//函数类型形参,调用自动转换为函数指针  
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关键字
decltype(add)* fuc2(int)//明确知道返回哪个函数,可用decltype关键字推断其函数类型,  

5 成员函数指针

5.1普通成员函数指针使用举例
class A//定义类A  
{  
private:  int add(int nLeft, int nRight)  {  return (nLeft + nRight);  }  public:  void fuc()  {  printf("Hello  world\n");  }  
};  typedef void(A::*PF1)();//指针名前需加上类名限定  PF1 pf1 = &A::fuc; //必须有&  A a;//成员函数地址解引用必须附驻与某个对象地址,所以必须创建一个队形  (a.*pf1)();//使用成员函数指针调用函数  
5.2 继承中的函数指针使用举例
class A  
{  
public:  void fuc()  {  printf("Hello fuc()\n");  }  void fuc2()  {  printf("Hello A::fuc2()\n");  }  
};  class B:public A  
{  
public:  virtual void fuc2()  {  printf("Hello B::fuc2()\n");  }  };  typedef void(A::*PF1)();  
typedef void(B::*PF2)();  PF1 pf1 = &A::fuc;  int main()         
{  A a;  B b;  (a.*pf1)();  //调用A::fuc  (b.*pf1)();   //调用A::fuc  pf1 = &A::fuc2;  (a.*pf1)();  //调用A::fuc2  (b.*pf1)();  //调用A::fuc2  PF2 pf2 = &A::fuc2;   (b.*pf2)(); //调用A::fuc2  
}  

6重载函数的指针

6.1 重载函数fuc
Void fuc();  
Void fuc(int);  
6.2 重载函数的函数指针
void (*PF)(int) = fuc;//PF指向fuc(int)  
int(*pf2)(int) = fuc;//错误没有匹配的类型  

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

转载自:https://www.cnblogs.com/lvchaoshun/p/7806248.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492826.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用异或运算交换两个任意类型变量

这篇文章中将使用C语言,实现交换两个任意类型变量的功能.说到任意类型用C让人感觉很难做,如果是C则使用模板函数就轻松搞定: template<class T> inline void swap(T& t1, T& t2) { T tmp; tmp t1; t1 t2; t2 tmp; } 先说下使用^来交换两个整数,其代码…

2019与下一个十年:我们将要放弃的和将要拥抱的

来源&#xff1a;资本实验室2019年&#xff0c;是连接21世纪前两个十年的过渡一年。在金融支付和商业领域中&#xff0c;2019年也有望成为激动人心的一年。在这一年中&#xff0c;每家企业、每个人都需要对过去十年中所追求的创新进行反思&#xff0c;并决定下一个十年前进的方…

C++中虚函数、纯虚函数、普通函数三者的区别

转载自&#xff1a;https://www.cnblogs.com/cj2014/p/7692707.html 1.虚函数(impure virtual)   C的虚函数主要作用是“运行时多态”&#xff0c;父类中提供虚函数的实现&#xff0c;为子类提供默认的函数实现。 子类可以重写父类的虚函数实现子类的特殊化。 如下就是一…

麦肯锡发布调研,揭开“那些引入人工智能的企业都怎么了 ”

来源&#xff1a;亿欧智库摘要&#xff1a;根据麦肯锡的最新调研显示&#xff0c;人工智能技术普遍上得到企业接纳&#xff0c;但仍有不少企业在入门时就面临“不知道咋开门”的状况。新技术带来新问题&#xff0c;企业该如何应对&#xff1f;根据麦肯锡在全球范围内的调研&…

深度学习、图像识别的基本概念

图像识别 图像识别概念&#xff1a; 我们对图像进行一些列的处理&#xff0c;将其有用的信息提取出来&#xff0c;进行划分归类&#xff0c;这就是图像识别。 图像识别目的&#xff1a; 将景物、图像、字符等信息经过预处理&#xff0c;然后进行识别&#xff0c;让计算机具…

PHP-php.ini中文版

今天细看了下配置文件 有很多没用过的 就从网上搜了一篇 常看看 ;;;;;;;;;;;;;;;; 简介 ;;;;;;;;;;;;;;;;; 本文并非是对英文版 php.ini 的简单翻译&#xff0c;而是参考了众多资料以后&#xff0c;结合自己的理解&#xff0c;增加了许多内容&#xff0c;; 包括在原有 php.ini …

重磅!我国建成首个自动驾驶封闭高速公路测试环境

来源&#xff1a;智车科技摘要&#xff1a;根据工业和信息化部、公安部、江苏省人民政府共建“国家智能交通综合测试基地”的总体规划和建设要求&#xff0c;公安部交通管理科学研究所坚持“自动驾驶汽车产业发展与安全行驶并重”的指导思想&#xff0c;依据《中华人民共和国公…

线性运算和非线性运算

线性运算是加法和数量乘法&#xff0c;对于不同向量空间线性运算一般有不同的形式&#xff0c;它们必须满足交换律&#xff0c;结合律&#xff0c;数量加法的分配律&#xff0c;向量加法的分配律。线性是指量与量之间按比例、成直线的关系&#xff0c;在空间和时间上代表规则和…

拖延症讲:反向遍历链表

今天感觉被面试官用很简单的题目虐了。。。。“如何高效等反向遍历单链表” 一般情况下会想到一个很笨的方法&#xff1a;计算个数&#xff0c;然后再根据个数每一次将遍历的索引减一。 第二种方式就是将原链表反过来&#xff0c;再遍历。如果要求不改变原有结构&#xff0c;可…

单反相机内部光线反射原理

单反相机是照相机的一种&#xff0c;以独特的取景方式而命名。 它的全称是&#xff08;可换&#xff09;单镜头反光式取景照相机&#xff0c;&#xff08;Single Lens Reflex Camera&#xff0c;缩写为SLR camera&#xff09;一般简称为单反相机。它的含义是拍摄和取景共用用一…

面部识别技术走到十字路口?

来源&#xff1a;雷锋网摘要&#xff1a;向左走&#xff0c;还是向右走&#xff1f;近日&#xff0c;面部识别技术又遭遇“突发事件”。本周二&#xff0c;由90个倡议团体组成的小组给三巨头AAM&#xff08;亚马逊、谷歌、微软&#xff09;写信&#xff0c;要求三家公司承诺不向…

我与ARM的那些事儿2JINLK烧录nor flash

前言 最近在研究mini2440的友善之臂&#xff0c;但是我拿着的是实验室早期买的开发板&#xff0c;在做裸机开发的过程中老是不能很好地使用最新版的minitools进行烧录&#xff0c;因而各种不爽&#xff0c;因为生成了bin文件不能很好地传到mini2440中&#xff0c;作为一个对开…

焦距及摄像机成像

焦距,本来是一个光学中的量,当一束平行光以与凸透镜的主轴穿过凸透镜时&#xff0c;在凸透镜的另一侧会被凸透镜汇聚成一点&#xff0c;这一点叫做焦点&#xff0c;焦点到凸透镜光心的距离就叫这个凸透镜的焦距。一个凸透镜的两侧各有一个焦点。 光心&#xff1a;可以把凸透镜…

基于opencv的gpu与cpu对比程序,代码来自opencv的文档中

原文链接&#xff1a; http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/gpu/gpu-basics-similarity/gpu-basics-similarity.html 代码中有错误&#xff0c;关于GpuMat OpenCV代码中没有对其进行操作符运算的重载&#xff0c;所有编译的时候有错误。对于GpuMat的运…

不只是华为/阿里/百度/小米/京东,AIoT已然成为资本与新兴企业都认可的赚钱方向...

来源&#xff1a;物联网智库整理发布摘要&#xff1a;当互联网的上半场结束之后&#xff0c;所有的互联网下半场都是重生意。随着AIoT越来越热门&#xff0c;这一概念已然成为巨头、资本以及新兴企业竞相角逐的热点。2019年注定是AIoT具有重要发展的一年&#xff0c;仅仅在刚过…

Opencv中的Laplacian(拉普拉斯算法)

下面的代码选自Opencv2.4.9源码文件opencv\sources\modules\imgproc\src文件夹下的deriv.cpp文件&#xff0c;该cpp文件中的Laplacian(…)函数源码&#xff0c;下面只显示了ksize1or3的情况&#xff0c; void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, …

机会与挑战:2019人工智能应用趋势预测

来源&#xff1a;资本实验室摘要&#xff1a;最近几天&#xff0c;印度人工智能数据分析公司Fractal Analytics宣布获得私募投资机构Apax Partners的2亿美元投资&#xff0c;估值达到了5亿美元。也是在近期&#xff0c;该公司的几位人工智能专家分别对2019年的人工智能应用趋势…

函数指针 如:void (*oper)(ChainBinTreee *p)

在C语言中&#xff0c;一个函数总是占用一段连续的内存区&#xff0c;而函数名就是该函数所占内存区的首地址。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量&#xff0c;使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。我们把这种指向函数的…

边缘检测中非极大值抑制简单解释

首先要明白的是: (a.) canny算子中非最大抑制(Non-maximum suppression)是回答这样一个问题: “当前的梯度值在梯度方向上是一个局部最大值吗?” 所以,要把当前位置的梯度值与梯度方向上两侧的梯度值进行比较. (b.) 梯度方向垂直于边缘方向, 这一点不要误解. - Q1: 插值…

哥德尔不完备定理”到底说了些什么?

来源&#xff1a;人机与认知实验室&#xff08;一&#xff09;【中文网上深入介绍哥德尔不完备定理的文章很少&#xff0c;我这篇文章写得很长&#xff0c;花了不少时间打磨它&#xff0c;希望能帮助到爱好数学与逻辑的人。文章把理解哥德尔不完备定理分为了五重&#xff0c;建…