指针函数的定义格式

指针函数的定义格式,第1张

类型名 函数名(函数参数列表);

其中,后缀运算符括号“()”表示这是一个函数,其前缀运算符星号“”表示此函数为指针型函数,其函数值为指针,即它带回来的值的类型为指针,当调用这个函数后,将得到一个“指向返回值为…的指针(地址),“类型名”表示函数返回的指针指向的类型”。

“(函数参数列表)”中的括号为函数调用运算符,在调用语句中,即使函数不带参数,其参数表的一对括号也不能省略。其示例如下:

int pfun(int, int);

由于“”的优先级低于“()”的优先级,因而pfun首先和后面的“()”结合,也就意味着,pfun是一个函数。即:

int (pfun(int, int));

接着再和前面的“”结合,说明这个函数的返回值是一个指针。由于前面还有一个int,也就是说,pfun是一个返回值为整型指针的函数。

返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。例如下面一个返回指针函数的例子: #include <stdioh> float find(float(pionter)[4],int n);//函数声明 int main(void) {     static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};     float p;     int i,m;     printf(Enter the number to be found:);     scanf(%d,&m);     printf(the score of NO%d are:\n,m);     p=find(score,m-1);     for(i=0;i<4;i++)         printf(%52f\t,(p+i));      return 0; }float find(float(pionter)[4],int n)/定义指针函数/ {     float pt;     pt=(pionter+n);     return(pt); }共有三个学生的成绩,函数find()被定义为指针函数,其形参pointer是指针指向包含4个元素的一维数组的指针变量。pointer+n指向score的第n+1行。(pointer+1)指向第一行的第0个元素。pt是一个指针变量,它指向浮点型变量。main()函数中调用find()函数,将score数组的首地址传给pointer

std::function其实就是一个 类模板 ,含有c的 函数指针 概念。

类模版std::function是一种通用、多态的函数封装。std::function的实例可以对 任何可以调用的目标实体 进行存储、复制、和调用 *** 作,这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等。

简要来说:std::function是将所有可调用的实体封装起来,形成了一个新的std::function对象,用户在使用的时候不需要再去一一调用实体,只需要使用新的std::function来调用各实体

如下,std::function作为 回调函数 使用,它可以调用任何有两个int形参的返回值为int的对象

又因为std::function兼容c的函数指针,所以它还包含函数指针应有的特性。但是它又和函数指针不同,函数指针只能指向一个函数,而 std::function可以指向任何可以被当做函数调用的对象

以下内容来自

因为调用initWithFunction会产生临时的std::function对象,属于右值,必须使用const,不然会报错

转移 *** 作std::move效率更高

std::bind完成了实体和函数地址的绑定,因为它的参数里面既有对象指针,又有函数指针,从而制造了一个std::function,然后std::function只要能正确处理那个this指针,那就能完成正确地调用了

bind是一种机制,可以预先把指定的可调用的实体的某些参数绑定到已有的变量,产生一个新的可调用实体。

它作为一个通用函数适配器,接收一个可调用对象,生成一个新的可调用对象来 适应原对象的参数列表

比如,存在一个这样的函数check_size,因为这是一个二元函数,当我们要将它作为find_if的参数,会出错。因为find_if只接受一元函数,那么如何解决呢?

一个方法是Lambda表达式,还有一个方法就是使用std::bind

下面这个bind的函数只有一个占位符,即只需要传入一个参数。它将check_size的第二个参数绑定在sz上,sz的值就是check_size的第二个参数的值,而check_size第一个参数需要传入

如果现在我们调用g(3,5),那么就相当于bind(f,a,b,5,c,3);

所以_1相当于传递的第一个参数,_2相当于传递的第二个参数以此类推。

需要注意: bind对于直接绑定的值,是以值传递的方式,对于用_1这类,是使用引用传递。bind的返回值是可以调用的实体,所以通常我们都会将它和function联合在一起使用。

有时候对于有些绑定的参数我们希望以引用方式传递,或者说要绑定的参数无法拷贝。

比如ostream 流对象是无法拷贝 的,那么我们希望将它传递给bind而不拷贝它,就需要使用 ref

ref返回一个对象,包含给定的引用,是可以拷贝的。

对于成员函数的绑定,我们一定需要一个调用者,也就是类的实例!

需要注意的是,bind 无法绑定重载函数 ,因为当重载函数的参数个数不相同时,bind也失去了它的意义。

在cocos2dx的源码中,我们经常可以看到function作为函数形参,而bind作为实参传入

//数组传递给函数时会退化成指针

 #include<iostream>

 using namespace std;

   

 template<int m>

 void func(int (&array)[m])

{

   

 }

   

int main()

 {       

     int a[2]={0,1};

     func(a);

}

 

// c++ 要求模板参数推导成功后,才能实例化生成函数进行调用。

//在决定函数类型时,数组统统弱化为指针,所以 int a [m],就是 int a,问题就在于 m 变没了,因此不可能从实参中推导了(因为没有必要),这样模板非类型形参 m 就推不出来了,所以只能自己指定。

//int (&a) [m] 不存在弱化的问题,所以 m 能够从实际调用中推出。

 

//其实模板也可以不用引用的。

#include<iostream>

using namespace std; 

template<int m=0>

void func(int array [m]){

int main(){ 

    int a[2]={0,1}; 

    func(a);

}    

c++11才支持函数模板默认参数

lambda表达式 是一个匿名函数,也就是没有函数名的函数。也叫闭包,闭就是封闭的意思,包就是函数。lambda表达式 其实就是一个函数对象,内部创建了一个重载() *** 作符的类。

捕获变量列表 -> 返回值类型(函数主体) ,lambda可以隐士返回,也就是返回值类型可以不用显示写出来。

c++和c#不一样,想在闭包里面使用外部变量,就必须先在捕获变量列表里面定义。有下面几种定义可供选择。

[]没有捕获任何变量

[=] 按值类型捕获Lambda 所在范围内所有可见的局部变量

[&] 按引用类型捕获Lambda 所在范围内所有可见的局部变量

[a] 按值类型捕获a变量

[&a] 按引用类型捕获a变量

[&,a] 值类型捕获a,引用类型捕获其余变量

[=,&a] 引用类型捕获a,其余按值类型捕获

[this] 可以使用 Lambda 所在类中的成员变量。

当然参数也可以是多个,比如[a,b,c,&d] [&a,b,&c,d]这样都是可以的。

注意一点,变量捕获是在lambda表达式被创建的时候。

函数指针就是即指向函数的指针。

定义格式一般是 返回值类型(函数指针名字)(参数),例如 int ( p)(int) double ( p)(string) void(p)(int)都是正确的函数指针定义。

下面看一个向函数指针传递lambda的例子:

输出结果为 1,在这里我们并没有用到变量捕获, 事实上c++不允许往函数指针传递lambda的时候进行变量捕获。 下面介绍function。

类模板std :: function是一个通用的多态函数包装器。 std :: function的实例可以存储,复制和调用任何可调用的目标 :包括函数,lambda表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针。(这句话是我抄的)

function声明格式 function<返回值(变量类型)>,例如function<int(int)>,function<void(int)>都是function的正确声明。

上面定义了一个返回值为void,接受一个int类型参数的function函数模板,右边是一个lambda表达式,值类型捕获a,输出的结果是func1 a=0 b=5。

再看下面一种情况

定义了一个返回值为void,接受一个int类型参数的function函数模板,显式返回a+b的值,输出5;

再看下面的情况

定义了一个返回值为void,按引用捕获a变量,接受一个int类型参数的function函数模板,隐式返回void,输出5,并且在最后改变了a的值a+=5。

细心的同学会发现,明明先调用了func3,后调用func2,为什么2还是输出5,那是因为捕获变量发生在lambda被创建的时候,把func2改成按类型捕获,或者将func3的声明和调用放到func2的前面,都会输出10。这一点还是要多多注意

没说清楚。DepthFirstVisit是什么?哪些函数是虚函数?函数指针要存起来吗?如果只是声明模板成员函数,很简单

class test{

    template<class T>

    void foo(T t);

};

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12182379.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存