本来说好要聊一聊命名空间的,因为最近在看C++lambda表达式的内容,所以借这个机会我们来好好聊一聊C++的闭包。

1.什么是闭包?

闭包(closure)是函数式编程的重要的语法结构。

闭包的概念其实很简单,一言以蔽之:闭包是带有上下文的函数。说白了,就是有状态的函数。也就是说一个局部变量n,在被函数对象给“封闭”在函数里,从而能把值保存了下来,让函数能够保存状态。(其实本质上就是一个类,用纯粹面向对象的方式理解,函数也是一个对象

扯概念很烦,我们直接上代码来看一看。这里我们用Python的代码来解释一下闭包。(后续我们再来详细聊聊C++之中是怎么样实现闭包的):

def getFun(n):
return lambda:n + n funA = getFun(10)
funB = getFun("abc") print(funA.func_closure[0].cell_contents)
print(funB.func_closure[0].cell_contents)

打印结果为:

10      //funcA的闭包变量
abc //funcB的闭包变量

由上述两个函数我们看到变量作为一种状态嵌入到函数由getFun返回的函数之中。不同的语言实现闭包的方式不同。Python以函数对象为基础,为闭包是通过函数对象的属性来保存闭包的变量。(这里在Python之中是一个tuple,从这里也可以看出,所谓的闭包本质上就是类属性的一个语法糖。

这里闭包解决了编程工作之中的两个痛点:

  • (1)突破了函数访问变量的作用域。
  • (2)可以动态添加函数属性,真是通过这种动态特性,可以让我们实现某些编程任务的时候变得很简洁。
  • (3)函数可定制化更佳,提高了函数的可移植性。

闭包的作用有很多,可以在python上实现动态代理,如装饰器等.......这里就不展开聊闭包的使用,接下来我们要来重点看看在C++之中是如何实现闭包的。

2.C++之中的闭包

C++相对于C的优越点就在于C++能够支持面向对象的特性,C语言之中在语法层面是不能支持闭包的。我们来看看C++之中有几种方式来支持闭包特性:

  • 重载类的operator() 操作符

    第一次看到用法的时候有点震惊,没想到重载()括号操作符之后可以将普通的类转变为Callable对象,当时觉得很Tricky。这种用法其实本质上是其他语法糖的基础,我们来看一看代码:
class Closure {
public:
Closure(int n):num(n){};
int operator()(int add) {
return num + add;
}
private:
int num;
}; int main() {
Closure clu(20);
cout << clu(50) << endl;
}

可以看到,重载了()操作符的类Closure摇身一变成为了一个函数,可以直接被调用。同时它也包含了对象成员,通过对象成员保存下来了函数的运行状态

  • lambda表达式

    喜欢函数式编程的同学最喜欢使用的工具了(C++11对于C++来说是一个很重要的版本),lambda表达式可以很方便的让我们定义一个匿名函数,我们来看看怎么用lambda表达式来实现闭包:
int main() {
int num = 20;
function<int(int)> clu = [num](int add) {return num + add;};
cout << clu(50) << endl;
}

使用lambda表达式实现同样的功能,代码就简洁明了许多。这里的clu是通过一个匿名类来实现的,所以每个lambda表达式都是独一无二的,我们只能使用function或auto来捕获它。这里lambda表达式通过[]操作符捕获外部变量,并且和函数绑定在了一起。

  • 参数绑定

    bind函数在C++11之中也被加入了标准库,我们来看看通过参数绑定是如何实现闭包的:
int addNum(int num,int add) {
return add + num;
} int main() {
auto clu = bind(addNum,placeholders::_1,20);
cout << clu(50) << endl;
}

通过bind函数,将20绑定到对应的参数add之上,而每次调用clu函数之时,参数会对应到_1的位置,也就是函数addNum的第一个参数num。通过bind的函数,我们可以将外部变量与和原函数绑定在了一起,并且生成了一个新的函数对象。

好的,关于C++之中的闭包就和大家聊到这里,希望大家在实际Coding之中可以用好它........

C++雾中风景7:闭包的更多相关文章

  1. 《Web 前端面试指南》1、JavaScript 闭包深入浅出

    闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...

  2. 干货分享:让你分分钟学会 JS 闭包

    闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述 ...

  3. 深入浅出JavaScript之闭包(Closure)

    闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...

  4. javascript之闭包理解以及应用场景

    半个月没写博文了,最近一直在弄小程序,感觉也没啥好写的. 之前读了js权威指南,也写了篇博文,但是实话实说当初看闭包确实还是一头雾水.现在时隔一个多月(当然这一段时间还是一直有在看闭包的相关知识)理解 ...

  5. js闭包 和 prototype

    function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...

  6. js闭包for循环总是只执行最后一个值得解决方法

    <style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...

  7. JavaScript学习笔记(二)——闭包、IIFE、apply、函数与对象

    一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...

  8. 带你一分钟理解闭包--js面向对象编程

    上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...

  9. 如何设计一门语言(七)——闭包、lambda和interface

    人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...

随机推荐

  1. 【转载】BP神经网络

    原文地址:http://blog.csdn.net/acdreamers/article/details/44657439 今天来讲BP神经网络,神经网络在机器学习中应用比较广泛,比如函数逼近,模式识 ...

  2. HDU 1027 Ignatius and the Princess II 排列生成

    解题报告:1-n这n个数,有n!中不同的排列,将这n!个数列按照字典序排序,输出第m个数列. 第一次TLE了,没注意到题目上的n和m的范围,n的范围是小于1000的,然后m的范围是小于10000的,很 ...

  3. TCP检验和

    TCP的检验和   检验和目的 目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动.如果接收方检测到检验和有差错,则TCP段会被直接丢弃. TCP在计算检验和时,要加上一个12字节的伪首 ...

  4. jQuery插件之ajaxFileUpload(异步上传图片并实时显示,并解决onchange后ajaxFileUpload失效问题)

    参考学习: 第一篇:http://www.cnblogs.com/kissdodog/archive/2012/12/15/2819025.html 第二篇:http://www.jb51.net/a ...

  5. Django Xadmin - 重构django admin

    一.Django admin的执行流程 https://www.cnblogs.com/weihengblog/p/9122509.html 我的博客,介绍了django admin执行流程 二.Xa ...

  6. php CI框架

    CodeIgniter 是一个小巧但功能强大的 PHP 框架,作为一个简单而“优雅”的工具包,它可以为 PHP 程序员建立功能完善的 Web 应用程序.如果你是一个使用共享主机,并且为客户所要求的期限 ...

  7. Extjs6设置Store、Ajax、form的请求方式(GET、POST)

    Extjs6 设置Store.Ajax.form的请求方式(GET.POST) Ajax请求和Form的submit方法设置请求方式和原来一样,使用method : 'POST'设置 // 表单提交 ...

  8. window时间同步机制的简单介绍

    1 window自身现在采用w32tm程序来进行时间校正,window自身携带NTP程序,但默认下时关闭的,默认的NTP时客户端. 2 w32tm时用来代替早期的时钟同步程序net  time 3 w ...

  9. java多线程-读写锁原理

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...

  10. 【笔记】jQuery插件开发指南

    原文链接:http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html (有部分增删和修改) jQuery插件开发模式 软件开发过程中是需要一定 ...