您的位置:首页 > 移动开发 > Cocos引擎

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函数

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进行绑定
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: