声明函数指针、回调函数、函数对象------c++程序设计基础、编程抽象与算法策略
声明函数指针

#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++程序设计基础、编程抽象与算法策略的更多相关文章
- typedef void(*Fun) (void)是什么意思 函数指针(回调函数) 和函数对象总结
https://blog.csdn.net/FreeApe/article/details/49124043 bool (*pf)(const string &,const string &a ...
- C语言笔记 08_函数指针&回调函数&字符串&结构体&位域
函数指针 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调用函数.传递参数. 函数指针变量的声明: / ...
- [Reprint]C++普通函数指针与成员函数指针实例解析
这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下 C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般 ...
- C++ 类的多态三(多态的原理--虚函数指针--子类虚函数指针初始化)
//多态的原理--虚函数指针--子类虚函数指针初始化 #include<iostream> using namespace std; /* 多态的实现原理(有自己猜想部分) 基础知识: 类 ...
- qsort中的函数指针,及函数解释
函数指针有何用 函数指针的应用场景比较多,以库函数qsort排序函数为例,它的原型如下: void qsort(void *base,size_t nmemb,size_t size , int(*c ...
- selector函数指针回调机制
selector可以叫做选择器,其实指的就是对象的方法,也可以理解为C语言里面的函数指针,在面向对象里面的对应概念. [self performSelector:@selector(Hidden) w ...
- 从成员函数指针生成可调用对象:function<>、mem_fn()和bind()
我们知道,普通函数指针是一个可调用对象,但是成员函数指针不是可调用对象.因此,如果我们想在一个保存string的vector中找到第一个空string,不能这样写: vector<string& ...
- C++学习之普通函数指针与成员函数指针
函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般函数的函数指针使用的比较多,而对指向类成员函数的函数指针则比较陌生.我最近也被问到了这方面的问题,心中 ...
- c++11 符号修饰与函数签名、函数指针、匿名函数、仿函数、std::function与std::bind
一.符号修饰与函数签名 1.符号修饰 编译器将c++源代码编译成目标文件时,用函数签名的信息对函数名进行改编,形成修饰名.GCC的C++符号修饰方法如下: 1)所有符号都以_z开头 2)名字空间的名字 ...
随机推荐
- thinkphp遇到的小问题,js文件中U方法不被解析
我想在js文件中写ajax, 写完发现异常, 本以为是js文件中不支持ajax 后来发现时地址解析错误. 也就是U方法在js文件中不被解析. 貌似thinkphp解析,tpl文件中的一些元素. js文 ...
- AJAX的流程是什么?
客户端产生js的事件 创建XMLHttpRequest对象 对XMLHttpRequest进行配置 通过AJAX引擎发送异步请求 服务器端接受请求并且处理请求,返回html或者xml内容 XML调用一 ...
- php文件上传总结
前言: 学习php中 1.表单代码: <html> <head> <title>文件上传</title> </head> <body ...
- C#编程技巧
拷贝/克隆(深度/浅拷贝).序列化.反射 Json/Xml 窗体的单例模式 https://www.cnblogs.com/imstrive/p/5426503.html 使用XmlSerialize ...
- MongoDB 学习笔记(一)—— 安装入门
注:我的环境是win7 32位. 下载安装 http://www.mongodb.org/downloads 解压即可.这里我重命名“mongodb”,存放的目录为E:\mongodb. 新建数据文件 ...
- seureCRT快捷键
前言 secureCRT 是一个非常不错的终端软件,在嵌入式开发过程中经常使用到,所以了解一下其快捷键操作是非常有必要的,可以提高开发效率. 复制:[ctrl] + [shift] + c 粘贴 ...
- 时区时差换算(GMT,UTC,PST,PDT)
2014年美国冬令时标准时间Stardand Time于11月2号开始实施,直到2015年3月8号为止. 冬令时,是指在冬天使用的标准时间.在使用日光节约时制(夏令时)的地区,夏天时钟拨快一小时,冬天 ...
- SpringMVC Controller 介绍(详细深刻)
一.简介 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Mo ...
- VMware设置及linux静态ip设置
1. VMWARE虚拟机NAT模式上网设置 1.1. VM虚拟机设置 1.1.1. 虚拟机全局设置 启动虚拟机选择[虚拟网络编辑器] 如果需要管理员权限点[更改设置],没有提示这忽略这一步 选 ...
- yii2 源码分析1从入口开始
我是在 backend 一步步打印的 很多地方我也是很模糊 .后来发现一位大神的文章(http://www.yiichina.com/tutorial/773) 参考文章自己动手开始写的 至于后来的 ...