Cocos2d-x之lambda表达式的使用
2016-03-08 19:45
471 查看
本篇博客来自star特530,转载请注明出处。http://blog.csdn.net/start530/article/details/19913611
Cocos2dx 3.0 版本后加入了lambda表达式,或者说C++ 11终于引入了lambda表达式,那么,什么是lambda表达式呢?
例如调用中的std::sort,ISO C++ 98 的写法是要先写一个compare函数:
然后,再这样调用:
然而,用ISO C++ 11 标准新增的Lambda表达式,可以这么写:
这样一来,代码是不是简洁多了呢?
由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导:
和其它语言的一个较明显的区别是Lambda和C++的类型系统结合使用,如:
下面讲下在cocos2dx 3.0 应该如何使用lambda:
我先创建一个menu ,如果不使用labmda,menu里 item 需再写一个回调函数,如下:
使用了lambda后,可以这么使用:
这种写法是不是简洁很多?当然了,也可以将回调 的代码单独取出来,这种写法的好处是可以多出调用callEnd。如下:
默认情况下,即捕获字段为 [] 时,lambda表达式是不能访问任何外部变量的,即表达式的函数体内无法访问当前作用域下的变量。
如果要设定表达式能够访问外部变量,可以在 [] 内写入 & 或者 = 加上变量名,其中 & 表示按引用访问,= 表示按值访问,变量之间用逗号分隔,比如 [=factor, &total] 表示按值访问变量 factor,而按引用访问 total。
用 & 引用来举个例子:假设点击按钮后,我要创建一个精灵。修改callEnd:
上面这种写法是错误的,因为表达式无法访问当前作用于的变量。下面继续改代码:
这样就没问题了。
上面的例子都只是简单的应用。在cocos2dx用到lambda 的地方还有很多,例如创建一个监听事件:
(因为是向下转型,上面代码中使用dynamic_cast转型更安全。dynamic_cast有类型检测功能,如果转型成功,则返回指定类型对象,失败则返回空指针。
如果是向上转型,则static_cast与dynamic_cast没有区别)
恩,就这样子吧。
Cocos2dx 3.0 版本后加入了lambda表达式,或者说C++ 11终于引入了lambda表达式,那么,什么是lambda表达式呢?
例如调用中的std::sort,ISO C++ 98 的写法是要先写一个compare函数:
bool compare(int & a, int & b) { return a > b; // 降序排序 }
然后,再这样调用:
sort(a, a+n, compare);
然而,用ISO C++ 11 标准新增的Lambda表达式,可以这么写:
sort(a, a + n, [](int a, int b){return a > b;}); // 降序排序
这样一来,代码是不是简洁多了呢?
由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导:
auto f = [](int a, int b){return a > b;});
和其它语言的一个较明显的区别是Lambda和C++的类型系统结合使用,如:
auto f = [=](int a, int b){return a > x;}); //x被捕获复制 int x = 0, y = 1; auto g = [&](int x){return ++y;}); //y被捕获引用,调用g后会修改y,需要注意y的生存期 bool(*fp)(int, int) = [](int a, int b){return a > b;}); //不捕获时才可转换为函数指针
下面讲下在cocos2dx 3.0 应该如何使用lambda:
我先创建一个menu ,如果不使用labmda,menu里 item 需再写一个回调函数,如下:
auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback,this)); void HelloWorld::menuCloseCallback(Object* sender) { Director::getInstance()->end(); }
使用了lambda后,可以这么使用:
auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", [](Object* sender) { Director::getInstance()->end();//直接在这里添加按钮要调用的代码 });
这种写法是不是简洁很多?当然了,也可以将回调 的代码单独取出来,这种写法的好处是可以多出调用callEnd。如下:
auto callEnd = [](Object* sender) { Director::getInstance()->end();//直接在这里添加按钮要调用的代码 }; auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", allEnd);
默认情况下,即捕获字段为 [] 时,lambda表达式是不能访问任何外部变量的,即表达式的函数体内无法访问当前作用域下的变量。
如果要设定表达式能够访问外部变量,可以在 [] 内写入 & 或者 = 加上变量名,其中 & 表示按引用访问,= 表示按值访问,变量之间用逗号分隔,比如 [=factor, &total] 表示按值访问变量 factor,而按引用访问 total。
用 & 引用来举个例子:假设点击按钮后,我要创建一个精灵。修改callEnd:
auto callEnd = [](Object* sender) { auto sp = Sprite::create("Hello.png"); sp->setPosition(Point(100,100)); this->addChild(sp,10);//这里报错 };
上面这种写法是错误的,因为表达式无法访问当前作用于的变量。下面继续改代码:
auto callEnd = [&](Object* sender) { auto sp = Sprite::create("Hello.png"); sp->setPosition(Point(100,100)); this->addChild(sp,10);//perfect };
这样就没问题了。
上面的例子都只是简单的应用。在cocos2dx用到lambda 的地方还有很多,例如创建一个监听事件:
// Make sprite1 touchable auto sprite1 = Sprite::create(); auto listener1 = EventListenerTouchOneByOne::create(); listener1->setSwallowTouches(true); listener1->onTouchBegan = [](Touch* touch, Event* event){ auto target = static_cast<Sprite*>(event->getCurrentTarget()); return false; }; listener1->onTouchMoved = [](Touch* touch, Event* event){ auto target = static_cast<Sprite*>(event->getCurrentTarget()); target->setPosition(target->getPosition() + touch->getDelta()); }; listener1->onTouchEnded = [=](Touch* touch, Event* event){ auto target = static_cast<Sprite*>(event->getCurrentTarget()); }; _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
(因为是向下转型,上面代码中使用dynamic_cast转型更安全。dynamic_cast有类型检测功能,如果转型成功,则返回指定类型对象,失败则返回空指针。
如果是向上转型,则static_cast与dynamic_cast没有区别)
恩,就这样子吧。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性