cocos2d-x-3.0学习笔记之std::function、std::bind

来源:互联网 发布:自学黑帽seo 编辑:程序博客网 时间:2024/05/18 00:41

在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进行绑定

0 0
原创粉丝点击