声明函数指针、回调函数、函数对象------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)名字空间的名字 ...
随机推荐
- shutil模块,ZipFile 和 TarFile 两个模块
高级的文件.文件夹.压缩包处理模块 shutil.copyfileobj(fsrc, fdst[, length])将文件内容拷贝到另一个文件中,可以部分内容 shutil.copyfile(src, ...
- oracle导入数据和编码问题
配置contrl文件 load data characterset utf8 append into table role_res_gold fields terminated by ';' TRAI ...
- 浅析bootstrap原理及优缺点
网格系统的实现原理,是通过定义容器大小,平分12份(也有平分成24份或32份,但12份是最常见的),再调整内外边距,最后结合媒体查询,就制作出了强大的响应式网格系统 网格系统的实现原理,是通过定义 ...
- SqlServer——临时表
1.表的类型: SqlServer数据库中分为两个表:永久表.临时表:通过表名的前缀区分. 永久表:与物理文件.C# 中的静态类 类似,任何用户均可对其执行操作并且相互影响: 临时表:简单的说就是使用 ...
- 去掉字符串中的html标签
public static string removeHtml(string html) { System.Text.RegularExpressions.Regex regex1 = new Sys ...
- Java微信公众平台开发(四)--回复消息的分类及实体的创建
转自:http://www.cuiyongzhi.com/post/42.html 前面有说道对接收到微信服务器消息后对消息的分类,当时主要分为普通消息和事件消息,这里我们要讲述的是我们在给用户回复的 ...
- 在VS13上编译通过的代码放在12上编译-错误:l __dtoui3 referenced in function _event_debug_map_HT_GROW
在VS13上编译通过的代码放在12上编译 遇到错误:l __dtoui3 referenced in function _event_debug_map_HT_GROW 1>------ 已启动 ...
- 21-从零玩转JavaWeb-多态详解
配套视频详解 多态思想 eclipse快捷键设置 多态的好处 多态方法调用 instanceof关键字 多态中字段注意点 一.什么是多态 既然子类是一种特殊的父类 那么我们可不可以认为 狗 ...
- phpmailer邮件类
<?php/** * 邮件类 * Enter description here ... * @author df * Mail::getMail()->sendMail(); * */cl ...
- python调用Go代码
Go 1.5发布了,其中包含了一个特性:可以编译生成动态链接库,经试验,生成的.so文件可以被python加载并调用.下面举个例子: 先写一个go文件main.go: package main imp ...