文档章节

C++ 实现简单的闭包

兔之
 兔之
发布于 2016/12/08 11:15
字数 591
阅读 748
收藏 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

© 著作权归作者所有

共有 人打赏支持
兔之
粉丝 68
博文 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,你说的也有道理,但是,多了解底...

万建宁
2018/07/17
0
0
有效使用 Lambda 表达式和 std::function [翻译]

翻译自 Dr. Dobb's 的一篇关于 C++11 的 lambda 表达式, 闭包 和 std::function 的文章 原文: Efficient Use of Lambda Expressions and std::function 作者: Cassio Neri 译文: 有效使用 La......

晨曦之光
2012/05/23
3.5K
0
FFLIB之FFLUA——C++嵌入Lua&扩展Lua利器

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

知然
2013/01/27
0
0
9 个开始使用 C++11 的理由

如果你的代码工作正常并且表现良好,你可能会想知道为什么还要使用C++ 11。当然了,使用用最新的技术感觉很好,但是事实上它是否值得呢? 在我看来,答案毫无疑问是肯定的。我在下面给出了9...

tsl0922
2012/05/14
9.3K
42
iOS学习笔记(十六)——数据库操作(使用FMDB)

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

sea_god
2014/08/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

面向对象接口多态

第3天 面向对象 今日内容介绍  接口  多态  笔记本案例 今日学习目标  写出定义接口的格式  写出实现接口的格式  说出接口中成员的特点  接口和抽象类的区别  能够说出使用多...

stars永恒
23分钟前
2
0
摄像头基础介绍

一、摄像头结构和工作原理. 拍摄景物通过镜头,将生成的光学图像投射到传感器上,然后光学图像被转换成电信号,电信号再经过模数转换变为数字信号,数字信号经过DSP加工处理,再被送到电脑中...

天王盖地虎626
24分钟前
2
0
浅谈一致性Hash原理及应用

在讲一致性Hash之前我们先来讨论一个问题。 问题:现在有亿级用户,每日产生千万级订单,如何将订单进行分片分表? 小A:我们可以按照手机号的尾数进行分片,同一个尾数的手机号写入同一片/...

Java干货分享
46分钟前
3
0
React SSR样式及SEO的实践

前一篇主要记录了一下SSR配置以及结合Redux的使用。这里简单说一下React SSR中样式处理和更优雅的SEO SSR样式 在React客户端渲染,添加样式很容易。写一个css样式文件,在对应组件中引用。标...

前端小攻略
53分钟前
5
0
华为手机太猛!余承东吹的牛今天都实现了

华为是世界上少有的在2B和2C领域同时取得成功公司。如今,华为消费者业务的营收,已经在华为总营收中占据“半壁江山”。 12月27日,华为董事长郭平在新年致辞中披露,预计2018年华为预计实现...

linux-tao
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部