本篇博客来自star特530,转载请注明出处。http://blog.csdn.net/start530/article/details/19909517
Cocos2dx 3.0 版本后加入了lambda表达式,或者说C++ 11终于引入了lambda表达式,那么,什么是lambda表达式呢?
例如调用
bool compare(int & a, int & b)
{
return a > b; // 降序排序
}
sort(a, a+n, compare);
sort(a, a + n, [](int a, int b){return a > b;}); // 降序排序
由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导:
auto f = [](int a, int b){return a > b;});
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();
}
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
[](Object* sender)
{
Director::getInstance()->end();//直接在这里添加按钮要调用的代码
});
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(event->getCurrentTarget());
return false;
};
listener1->onTouchMoved = [](Touch* touch, Event* event){
auto target = static_cast(event->getCurrentTarget());
target->setPosition(target->getPosition() + touch->getDelta());
};
listener1->onTouchEnded = [=](Touch* touch, Event* event){
auto target = static_cast(event->getCurrentTarget());
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
本篇博客来自star特530,转载请注明出处。http://blog.csdn.net/start530/article/details/19909517