1010
技術社區[雲棲]
Cocos2dx 3.0 過渡篇(十二) lambda表達式的使用
本篇博客來自star特530,轉載請注明出處。https://blog.csdn.net/start530/article/details/19913611
Cocos2dx 3.0 版本後加入了lambda表達式,或者說C++ 11終於引入了lambda表達式,那麼,什麼是lambda表達式呢?
例如調用<algorithm>中的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;});
[cpp] view
plaincopy
- 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<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);
本篇博客來自star特530,轉載請注明出處。https://blog.csdn.net/start530/article/details/19913611
最後更新:2017-04-03 12:56:12