cocos2d-x-3.0学习笔记之std::function、std::bind
2016-10-22 15:45
411 查看
在C++中,可调用体主要包括函数,函数指针,函数引用,可以隐式转换为函数指定的对象,或者实现了opetator()的对象(即C++98中的functor)。C++0x中,新增加了一个std::function对象,std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(我们知道像函数指针这类可调用实体,是类型不安全的)。好了,具体概念不深究,由于自己也是第一次接触这个,仅仅是将std::function作为函数指针回调的替代品,具有可靠的安全性和更高的灵活性。
由于自己在工作中遇到的难题是,需要写一个接口以实现某个功能,而这个功能会被其子类调用,因此很自然的想到在基类中实现这个功能,但是这个功能会调用其子类的成员函数,即这是一个典型的回调问题,此时首先想到的是利用函数指针来做,但这可能涉及到许多的安全转换问题,再尝试了一番失败后就放弃了,然后由于自己是做cocos2d-x开发的,在cocos2d-x的库代码里,就有许多的回调使用了std::function来做回调函数,因此,首先来分析cocos引擎是如何做的,在这里我分析了 MenuItemImage类的create函数
进入create函数内部继续跟踪
继续找这个函数的定义
可以看到其为 typedef std::function
总结:std::function和std::bind的使用只要按照其规则还是非常简单的,但是有几点需要注意:
1.std::function作为函数形参时,必须在前加const,否则会报错
2.被调用的函数为累的成员函数,必须用std::bind进行绑定
由于自己在工作中遇到的难题是,需要写一个接口以实现某个功能,而这个功能会被其子类调用,因此很自然的想到在基类中实现这个功能,但是这个功能会调用其子类的成员函数,即这是一个典型的回调问题,此时首先想到的是利用函数指针来做,但这可能涉及到许多的安全转换问题,再尝试了一番失败后就放弃了,然后由于自己是做cocos2d-x开发的,在cocos2d-x的库代码里,就有许多的回调使用了std::function来做回调函数,因此,首先来分析cocos引擎是如何做的,在这里我分析了 MenuItemImage类的create函数
MenuItemImage* create(const std::string& normalImage, const std::string& selectedImage, Ref* target, SEL_MenuHandler selector); //这个类是用图片创建一个菜单选项,然后最后一个参数传进去的就是点击菜单时的回调处理函数 //然后我们进入SEL_MenuHandler查看其定义 typedef void (Ref::*SEL_CallFunc)(); typedef void (Ref::*SEL_CallFuncN)(Node*); typedef void (Ref::*SEL_CallFuncND)(Node*, void*); typedef void (Ref::*SEL_CallFuncO)(Ref*); typedef void (Ref::*SEL_MenuHandler)(Ref*); typedef void (Ref::*SEL_SCHEDULE)(float); //通过定义发现cocos定义了许多的函数指针用来处理不同的回调需求,在这里我们只需要了解selector是一个函数指针即可
进入create函数内部继续跟踪
MenuItemImage * MenuItemImage::create(const std::string& normalImage, const std::string& selectedImage, Ref* target, SEL_MenuHandler selector) { return MenuItemImage::create(normalImage, selectedImage, "", std::bind(selector, target, std::placeholders::_1)); } //可以看到其调用了另外一个create函数,记下最后的一个参数:std::bind(selector, target, std::placeholders::_1)
继续找这个函数的定义
MenuItemImage * MenuItemImage::create(const std::string& normalImage, const std::string& selectedImage, const ccMenuCallback& callback) { return MenuItemImage::create(normalImage, selectedImage, "", callback); } //其最后一个参数ccMenuCallbac寻找其定义如下图所示
可以看到其为 typedef std::function
typedef std::function<void(Ref*)> My_func; void f(const My_func &pt){...} //然后调用f时 std::bind(&需要调用的类的成员函数的地址, 调用这个函数的类的对象(this), std::placeholders::_1) //最后一个参数std::placeholders::_1为参数占位符,表示当前还未确定,也可以直接传递一个实参进去
总结:std::function和std::bind的使用只要按照其规则还是非常简单的,但是有几点需要注意:
1.std::function作为函数形参时,必须在前加const,否则会报错
2.被调用的函数为累的成员函数,必须用std::bind进行绑定
相关文章推荐
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- 【很nice的一篇文章】c++11特性与cocos2d-x 3.0之std::bind与std::function
- C++11学习笔记之三lamda表达式,std::function, std::bind
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第三步---主角开跑&同时带着刚体
- cocos2d-x-3.0 Windos 新建项目(coco2d-x 学习笔记一)
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》第一步--- 开始界面
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》 完结篇--源码放送
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第六步--金币&岩石添加并且管理
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》第四步--地图循环&主角添加动作
- cocos2d-x 3.0 学习笔记: 一个可以拖拽的Label及schedule的应用
- 【Cocos2D-X 学习笔记】Cocos2D-x 3.0+VS开发环境搭建[使用Python]