文档章节

C++ 实现简单的闭包

兔之
 兔之
发布于 2016/12/08 11:15
字数 591
阅读 725
收藏 14

这里的闭包指的是一个闭包类,这个闭包类使用一个通用的辅助接口函数(如 NewCallback)来生成。在生成的时候传入需要使用的函数指针以及这个函数将要使用到的参数,生成闭包工具类后再使用一个通过的辅组函数(如 Run)让函数指针执行。闭包将函数和参数封装到类中,在一定的场景下进行使用,这就是闭包的作用。

示例

#include <iostream>
#include <string>

class Closure {
public:
    Closure() {}
    ~Closure() {}

    virtual void Run() = 0; //纯虚函数
};

template <typename Arg1>
class FunctionClosure1 : public Closure {
public:
    typedef void (*FunctionType)(Arg1);

    FunctionClosure1(FunctionType f, Arg1 arg1) :
        _f(f),
        _arg1(arg1) {
        }
    ~FunctionClosure1() {
    }

    virtual void Run() {
        _f(_arg1);
        delete this;
    }
private:
    FunctionType _f;
    Arg1 _arg1;
};

template <typename Arg1>
Closure* NewCallback(void(*function)(Arg1), Arg1 arg1) {
    return new FunctionClosure1<Arg1>(function, arg1);
}

// 带一个参数的函数
template<typename type>
void foo(type data) 
{
    std::cout << "foo data=" << data << std::endl;
}

int main()
{
    Closure* closure;
    closure = NewCallback(foo<std::string>, std::string("titus"));
    //等价于 closure = new FunctionClosure1<std::string>(foo<std::string>, std::string("titus"));
    closure->Run();
    //自己释放 delete closure
    return 0;
}

Closure 定义为纯虚类,不能实例化,必须由子类实现它的虚函数后再才能实例化。

FunctionClosure1 为 Closure 的子类,定义为模版类,可以定制传入参数的类型。它有两个私有成员,函数指针成员 _f,参数 _arg1,在成员方法 Run 中会让函数 _f 传入参数 _arg1 进行调用。而函数指针成员是在类初始化时传入的,相当于函数也是可以定制的。运行完之后 delete this,这是因为 NewCallback 在堆上 new 了一个对象,这里自动进行资源释放,当然也可以自己释放。

NewCallback 是一个辅助函数,用来生成子闭包类,它需要传入函数指针和参数。

在使用时,父指针指向 NewCallback创建的子类,同时传入函数指针和参数,最后调用子类继承实现的 Run 方法。

这么看来,闭包可以看成是对回调函数的封装。

标准库写法

头文件引入 functional 标准库,用 C++11 的写法也可以实现上述例子

std::function<void(string)> std_closure=foo;
std_closure(string("test std"));

使用 lambda 表达式

std::function<void()> std_closure = []() {foo(string("test lambda"));};
std_closure();

参考

http://www.cnblogs.com/Aion/p/3449756.html

http://yingshin.github.io/c/cpp/2015/12/01/closure-implement-in-C++

http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html

© 著作权归作者所有

共有 人打赏支持
兔之
粉丝 66
博文 247
码字总数 95896
作品 7
深圳
程序员
加载中

评论(6)

兔之
兔之

引用来自“Windoze”的评论

还不如这样:
`std::function<void()> closure=[=](){ foo(some_string_from_outside); };`
可以这么写,这篇文章相当于简单实现下类 function 的功能。
Windoze
Windoze
还不如这样:
`std::function<void()> closure=[=](){ foo(some_string_from_outside); };`
兔之
兔之

引用来自“magiclogy”的评论

无论是函数对象还是lambda都比这个靠谱吧?
函数对象的函数计算逻辑是写在 () 运算符里,闭包类的函数是从外面传入,后者具有更好的封装性。
兔之
兔之

引用来自“magiclogy”的评论

无论是函数对象还是lambda都比这个靠谱吧?
和 lambda 表达式一样,异步回调。
阿小莫
阿小莫
看了3遍我还没搞明白这种实现方式应用在什么场景?
m
magiclogy
无论是函数对象还是lambda都比这个靠谱吧?
深入分析golang多值返回以及闭包的实现

一、前言 golang有很多新颖的特性,不知道大家的使用的时候,有没想过,这些特性是如何实现的?当然你可能会说,不了解这些特性好像也不影响自己使用golang,你说的也有道理,但是,多了解底...

万建宁
07/17
0
0
FFLIB之FFLUA——C++嵌入Lua&扩展Lua利器

摘要: 在使用C++做服务器开发中,经常会使用到脚本技术,Lua是最优秀的嵌入式脚本之一。Lua的轻量、小巧、概念之简单,都使他变得越来越受欢迎。本人也使用过python做嵌入式脚本,二者各有特...

知然
2013/01/27
0
0
C++11 中值得关注的几大变化

源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 (and Why You Should Care),赖勇浩做了一个中文翻译在这里。所以,我就不翻译了,我在这里仅对文中提到的这些变...

雅各宾
2014/01/17
0
0
【转载】数据结构利器之私房STL

数据结构利器之私房STL 此系列的文章适合初学有意剖析STL和欲复习STL的同学们。 学过c++的同学相信都有或多或少接触过STL。STL不仅仅是c++中很好的编程工具(这个词可能有点歧义,用类库更恰...

悠米海
2012/12/02
0
0
iOS学习笔记(十六)——数据库操作(使用FMDB)

iOS中原生的SQLite API在使用上相当不友好,在使用时,非常不便。于是,就出现了一系列将SQLite API进行封装的库,例如FMDB、PlausibleDatabase、sqlitepersistentobjects等,FMDB (https:/...

sea_god
2014/08/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spark Load Data and Export Data

Load_Data_Command 一、导入数据-加载csv文件数据作为spark 临时表DataSource(不需要提前创建表,方便数据分析) 该命令将csv文件导入到临时表中,命令格式为 load data '文件路径' table [...

Avner
25分钟前
2
0
CDH5.13离线安装Spark2.3详细步骤

简介: 在我的CDH5.13集群中,默认安装的spark是1.6版本,这里需要将其升级为spark2.x版本。经查阅官方文档,发现spark1.6和2.x是可以并行安装的,也就是说可以不用删除默认的1.6版本,可以直...

hblt-j
29分钟前
2
0
Add XSS protection headers on Nginx

Add XSS protection headers on Nginx Add the following line in the http or server part of your Nginx configuration : ... # XSS Protection add_header X-Frame-Opt......

idoz
30分钟前
1
0
cmake windows 配置xp toolset

MPRO
36分钟前
2
0
day125-20181023-英语流利阅读-待学习

外卖员不要哭,打零工不容易 雪梨 2018-10-23 1.今日导读 上期我们讲到,有人认为:“零工经济”虽然没有占领全世界,但它剥夺了劳动者的合法权利,加剧了工作的不稳定性,那么“零工经济”是...

飞鱼说编程
48分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部