闭包(closure)

这篇文章中知道有闭包这个东西,开始去网上查,对此概念理解都说的云里雾里好像很神奇,其实最后看下来,在c++中,只是函数对象出现恰好符合了闭包的定义,并没有什么新的机制,一点点特别的机制都没。至少在上面文章中,所谓的闭包就是一个“能够保存状态的函数对象”,其实所有函数对象都有这个特性,所以说c++中,一个函数对象是一个闭包我感觉也是ok的,但是和js中的闭包好像是有点不同的。

在js中,一个闭包所关联的“作用域”是可以关联的,有点像智能指针,如果js中的“函数对象”关联了一个全局的变量,那么这个变量是一直会在内存中的,只有当函数对象的生命周期结束的时候,那个全局的变量才结束。也可能这个和js的垃圾回收机制有点关系,可能是跟智能指针一样,有人引用就不会释放,函数对象中相当于对真实对象一次引用,而不是刻意为了什么“闭包”才有这种特性的,所以js中的闭包与c++中的其实又是一样的,只不多有自动的垃圾回收机制,就是一个有状态的函数对象。下面是wiki上的解释:

In programming languages, a closure (also lexical closure or function closure) is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables (also called free variables or upvalues) of that function.A closure—unlike a plain function pointer—allows a function to access those non-local variables even when invoked outside its immediate lexical scope. The following program fragment defines a (higher-order) function startAt with a local variable x and a nested function incrementBy. This nested function incrementBy has access to x, because x is in its lexical scope, even though it is not local to incrementBy. The function startAt returns a closure containing a reference to the function incrementBy, which adds the y value to the x value, and a reference to the variable x, so incrementBy will know where to find it once invoked: ``` function startAt(x) function incrementBy(y) return x + y return incrementBy

variable closure1 = startAt(1) variable closure2 = startAt(5) ```

Invoking the variable closure1 (which is of function type) with closure1(3) will return 4, while invoking closure2(3) will return 8. While closure1 and closure2 are both references to the function incrementBy, the associated environment will bind the identifier x to two distinct variables in the two invocations, leading to different results.

“闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。” 说了那么多,在c++中就是个函数对象,“function closure”,在c++中可以对应函数对象。

Table of Contents