声明函数指针

#include<iostream>
using namespace std;
double a(double aa) { return aa; }
int main() {int aa = 9;
a(1.0); double(*fn)(double) = a;;
cout << a(1.0)<<endl;
cout << fn(1.0) << endl;
cout << fn << endl;
cout << &fn << endl;
cout << *fn << endl; }

  结果:

1
1
00821488
00F3FB70
00821488

回调函数

#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
void a(int t) { cout << t << endl; }
void aa(int t) { cout << t*t << endl; }
void callback(void(*fn)(int t),int g) { fn(g); }  //映射函数
int main() {
callback(a, 9);
callback(aa,9); }

  结果

9
81

  

回调函数还没懂应用在哪。

回调函数的限制

  向回调函数中所传递的信息超过了映射函数所能提供的参数。

解决

  函数指针在它们的效用中被限制,因为它们无法将函数与用户提供的数据一起提供。所以需要一种策略:它将回调函数与用户提供的数据封装成一个单独的单元。即函数类(function class)(通过重载operateor()将对象本身作为方法)。这些类的实例称为函数对象(function object)或函子(functor)。

函数对象的简单例子

  例如,函数对其参数值加1:

int add1(int x)
{return x+1;}

  现在改需求了,给定一个整型常量k,对参数值加k。

int addk(int x)
{return x+k;}

  k可为任意整数。你不可能实现与k相同数目的函数。你需要创建一个封装两个构件的函数类:一个变量记录k的值,另一个重载operator(),以便给操作符向其参数增加存储的k值。示例

#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
class AddFunction {
public:
AddFunction(int k) { this->k = k; }
int operator()(int x) { return x + k; }
private:
int k;
};
int main() {
AddFunction add1 = AddFunction(1);
AddFunction add17 = AddFunction(17);
cout << add1(100) << endl;
cout << add17(25) << endl;
}

  结果

101
42

  

向映射函数传递函数对象

  使用函数对象的策略可以解决映射函数向回调函数传递额外信息的问题。

#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
class AddFunction {
public:
AddFunction(int k) { this->k = k; }
int operator()(int x) { return x + k; }
private:
int k;
};
void callback(AddFunction a, int g) { cout << a(g) << endl; }
int main() {
AddFunction aa(8);
callback(aa,9);
}

  结果

17

  

编写以函数作为参数的函数

  1、函数指针

void callback(void(*fn)(int t),int g) { fn(g); }

  2、函数对象

c++通过使用模板函数来实现任何以函数对象作为参数的函数的方式来解决这个问题。原型如下

template <typename FunctionClass>
void callback(FunctionClass a, int g)

  示例

#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
class AddFunction {
public:
AddFunction(int k) { this->k = k; }
int operator()(int x) { return x + k; }
private:
int k;
};
template <typename FunctionClass>
void callback(FunctionClass a, int g) { cout << a(g) << endl; }
int main() {
AddFunction aa(8);
callback(aa,9);
}

  传递给callback的值可以是任何类型。当编译器试图展开callback模板函数时,如果该类型不能重载函数调用操作符以至于不能获得期望的参数,那么编译器就会报错。

c++程序设计基础、编程抽象与算法策略

声明函数指针、回调函数、函数对象------c++程序设计基础、编程抽象与算法策略的更多相关文章

  1. typedef void(*Fun) (void)是什么意思 函数指针(回调函数) 和函数对象总结

    https://blog.csdn.net/FreeApe/article/details/49124043 bool (*pf)(const string &,const string &a ...

  2. C语言笔记 08_函数指针&回调函数&字符串&结构体&位域

    函数指针 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调用函数.传递参数. 函数指针变量的声明: / ...

  3. [Reprint]C++普通函数指针与成员函数指针实例解析

    这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下   C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般 ...

  4. C++ 类的多态三(多态的原理--虚函数指针--子类虚函数指针初始化)

    //多态的原理--虚函数指针--子类虚函数指针初始化 #include<iostream> using namespace std; /* 多态的实现原理(有自己猜想部分) 基础知识: 类 ...

  5. qsort中的函数指针,及函数解释

    函数指针有何用 函数指针的应用场景比较多,以库函数qsort排序函数为例,它的原型如下: void qsort(void *base,size_t nmemb,size_t size , int(*c ...

  6. selector函数指针回调机制

    selector可以叫做选择器,其实指的就是对象的方法,也可以理解为C语言里面的函数指针,在面向对象里面的对应概念. [self performSelector:@selector(Hidden) w ...

  7. 从成员函数指针生成可调用对象:function<>、mem_fn()和bind()

    我们知道,普通函数指针是一个可调用对象,但是成员函数指针不是可调用对象.因此,如果我们想在一个保存string的vector中找到第一个空string,不能这样写: vector<string& ...

  8. C++学习之普通函数指针与成员函数指针

    函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般函数的函数指针使用的比较多,而对指向类成员函数的函数指针则比较陌生.我最近也被问到了这方面的问题,心中 ...

  9. c++11 符号修饰与函数签名、函数指针、匿名函数、仿函数、std::function与std::bind

    一.符号修饰与函数签名 1.符号修饰 编译器将c++源代码编译成目标文件时,用函数签名的信息对函数名进行改编,形成修饰名.GCC的C++符号修饰方法如下: 1)所有符号都以_z开头 2)名字空间的名字 ...

随机推荐

  1. 支付宝pc端支付接入PHP实现

    引入支付宝接口 放入一个插件库中,方便管理 创建支付类 1.发起支付 public function init() { $order_id = $_REQUEST['order_id']; $orde ...

  2. java成神之——注释修饰符

    注释修饰符 自定义注释 元注释 通过反射在runtime访问注释 内置注释 多注释实例 错误写法 使用容器改写 使用@Repeatable元注释 注释继承 使用反射获取注释 获取类的注释 获取方法的注 ...

  3. 关于性能测试中LR的pacing time设置的相关实验

    最近项目中遇到相关性能测试不同方法产生的争议,我这就这个问题在测试环境做了个实验,得出一些指标数据间的有趣关系,供大家讨论学习: 预备知识点: 业界有个TPS ,ART和实际并发量三者间的模拟换算公式 ...

  4. krpano之鼠标样式修改

    引入cursors.js. cursors.js代码: <krpano > <events onxmlcomplete="action(qtvrcursor);" ...

  5. OO设计基本原则

    OO本身就是一种大的设计模式,它是随着软件规模越来越大产生出来帮助人们建模和开发的理念,生来就带着封装.继承.多态等可复用基因.为了充分发挥这些基因的功效,使用者需要遵守一定的原则,就是所谓的面向对象 ...

  6. MySQL MVCC原理

    1 MVCC基本原理 MVCC:多版本并发控制(MVCC,Multiversion Currency Control).一般情况下,事务性储存引擎不是只使用表锁,行加锁的处理数据,而是结合了MVCC机 ...

  7. 关于苹果safari浏览器登陆时Cookie无法保存的问题

    前段时间,修改了登录处理后给到客户端浏览器Cookie的内容,新增了一个姓名的value,发现safari不能保存该Cookie的内容,同时Chrome.firefox.ie等浏览器都能正常的访问,直 ...

  8. 22-从零玩转JavaWeb-代码块

    配套详解视频 局部代码块与初始化代码块 面向对象-静态代码块 代码块总结 组合关系与类的加载 静态代码块及字段初始化练习 一.什么是代码块 在类中或方法当中 使用{}括起来的一段代码 就称它是一个代码 ...

  9. Spring总结七:AOP动态代理的实现

    Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类. 首先我们来用代码简单演示jdk动态代理: 现在有一个商品的增删改查的操作 /** * 商品操作接口 ...

  10. Python 安装selenium

    一.报错信息 No module named 'selenium' 二.系统环境 操作系统:Win10 64位 Python版本:Python 3.7.0 三.安装参考 1.使用pip安装seleni ...