Cocos2dx3.x中提供了对C++11标准的支持,其中Lambda表达式、function模板、bind模板在游戏编程中比较常用,本文简要介绍一下这三个C++11方面的特性。

1.Lambda表达式

(1)Lambda表达式语法格式:[捕捉列表](参数列表)<mutable>->返回值类型{函数体}
(1.1).
捕捉列表:捕捉列表能够捕捉上下文的变量供lambda函数使用。捕捉列表有如下几种形式:
[var]:
按值传递方式捕捉变量var
[=]:
按值传递方式捕捉父作用域所有变量,包括this
[&]:
按引用传递方式捕获父作用域所有变量,包括this
[&var]:
按引用传递方式捕获变量var
[this]
:按值传递方式捕获当前的this指针,这样就可以使用lambda表达式所在类的所有成员
(1.2).
参数列表:lambda函数参数
(1.3).mutable:
默认lambda函数是const的,如果你不需要const的,加上mutable取消其常量性
(1.4).
返回值类型:如果不需要返回值类型,可以和->一起省略
(1.5).
函数体:可以使用参数列表的参数和捕捉列表的参数(2)Lambda表达式程序示例

#include <iostream>

using namespace std;

class TestLambda
{
public:
	void testFunc();
public:
	int data;
};


void TestLambda::testFunc()
{
	int var1 = 1;
	int var2 = 2;

	/*无捕捉、无参数lambda函数*/
	auto fun1=[](){std::cout << "无捕捉、无参数lambda函数" << endl; };
	fun1();

	/*捕捉this指针*/
	auto fun2=[this](){
		this->data = 10;
	};
	fun2();

	/*用值传递方式捕捉特定变量*/
	auto fun3=[var1]()mutable{
		std::cout << "用值传递方式捕获到了"<<var1 << endl;
		var1 = 11;
	};
	fun3();
	std::cout << "var1改变了吗?" + var1 << endl;


	/*用值传递方式捕获所有变量,包括this*/
	auto fun4=[=](){
		std::cout << var1 << " " << var2 << " " << this->data << endl;
	};
	fun4();

	/*用引用传递捕获特定变量*/
	auto fun5=[&var2](){
		std::cout << var2 << endl;
		var2 = 22;
	};
	fun5();
	std::cout << "var2变了吗?"<<var2 << endl;

	/*用引用传递捕获所有变量,包括this*/
	auto fun6=[&](){
		std::cout << var1 << " " << var2 << " " << this->data << endl;
	};
	fun6();

	/*带参数的lambda*/
	auto fun7=[=](int var3){
		std::cout << "var1+var2+var3=" << var1 + var2 + var3 << endl;
	};
	fun7(3);

	/*带参数和返回值的lambda*/
	auto fun8 = [this](int var4)->int{
		return this->data - var4;
	};
	std::cout << fun8(10) << endl;

}


int main()
{
	TestLambda t1;
	t1.data = 20;
	t1.testFunc();
	return 0;
}

2.function模板:function是一个函数包装模板类,提供了泛型回调机制。function和函数指针比较类似,优点在于它允许用户在目标的实现上具有更大的弹性,即允许目标是普通函数,仿函数对象,类成员函数,甚至lambda表达式。

(1).function对象声明:function<返回值类型(参数类型)> 对象名

例:function<int(int,int)>f;//声明了一个返回值类型为int,两个参数皆为intfunction对象f

特别地,由于类的成员函数含有一个隐含的参数this指针,function对象声明如下:(类,参数列表)> f;

例:classCAdd

{

public:

int add(int a,int b){returna+b;}

}

function<int(CAdd,int,int)> f=&CAdd::add;

CAdd c;

f(c,2,3);

(2)function模板使用举例:

#include <iostream>
#include<functional>

using namespace std;

class TestFunction
{
public:
	int add(int a,int b)
	{
		return a + b;
	}

	static void test()
	{
		cout << "类静态成员函数" << endl;
	}
};

int max(int a,int b)
{
	return a > b?a:b;
}

int main()
{
	/*普通函数*/
	function<int(int,int)> f1 = max;
	cout << f1(2,3) << endl;

	/*类成员函数*/
	function<int(TestFunction,int)> f2 = &TestFunction::add;
	TestFunction t;
	cout << f2(t,3) << endl;

	/*类静态函数*/
	function<void()> f3 = TestFunction::test;
	f3();

	/*lambda表达式*/
	function<int(int,int)> f4 = [](int a,int b)->int{
		return a + b;
	};
	cout<<f4(2,3)<<endl;

	return 0;
}

3.bind模板:bind是一个用于函数绑定的模板。bind可以绑定普通函数,仿函数,类成员函数等等。对于某个函数进行绑定时,可以指定全部或部分参数,还可以调整参数的顺序。对于未指定的参数,可以用占位符std::placeholders::_1,std::placeholders::_2,std::placeholders::_3...来代替,其中_1表示参数表里的第一个参数。(1).bind使用示例:

#include<iostream>
#include<functional>

using namespace std;

class TestBind
{
public:
	int add(int a,int b)
	{
		return a + b;
	}
};


void fun1(int a,float b,char c)
{
	cout << a << '\t' << b << '\t' << c << endl;
}

class MaxFunctor
{
public:
	int operator()(int a,int b)
	{
		return a > b ? a : b;
	}
};

int main()
{
	/*普通函数*/
	auto testBind1 = bind(fun1,placeholders::_1,placeholders::_2,placeholders::_3);
	testBind1(1,1.0f,'1');
	/*使用占位符*/
	auto testBind2 = bind(fun1,std::placeholders::_1,'2');
	testBind2(2.0f,2);

	/*仿函数对象*/
	MaxFunctor max;
	auto testBind3 = bind(max,placeholders::_2);
	cout << testBind3(2,3) << endl;

	/*类成员函数*/
	TestBind t;
	auto testBind4 = bind(&TestBind::add,t,placeholders::_2);
	cout << testBind4(2,3) << endl;

	return 0;
}

4.综合示例:利用function,bind等特性实现一个处理输入的委托。

#include<iostream>
#include<functional>
#include<vector>

using namespace std;

class Event//仅供测试
{

};

class Touch//仅供测试
{

};

class InputHandler
{
public:
	static InputHandler* getInstance();
	void onTouch(Event*,Touch*);
	friend void operator+=(InputHandler*,function<void(Event*,Touch*)>);

private:
	InputHandler();
	virtual ~InputHandler();

private:
	static InputHandler* instance;
	vector<function<void(Event*,Touch*)>> myDelegate;
};

InputHandler* InputHandler::instance = new InputHandler;

InputHandler::InputHandler()
{

}

InputHandler::~InputHandler()
{
	if (instance != nullptr)
		delete instance;
}

InputHandler* InputHandler::getInstance()
{
	return instance;
}

void operator+=(InputHandler* in,Touch*)> f)
{
	in->myDelegate.push_back(f);
}

void InputHandler::onTouch(Event* e,Touch* t)
{
	for (auto f : myDelegate)
	{
		f(e,t);
	}
}

/*类成员函数*/

class TestInput
{
public:
	void fun1(Event* e,Touch* t)
	{
		cout << "fun1被调用" << endl;
	}
};

/*仿函数对象*/

class TestFunctor
{
public:
	void operator()(Event* e,Touch* t)
	{
		cout << "仿函数对象被调用" << endl;
	}
};

/*普通函数*/
void fun2(Event* e,Touch* t)
{
	cout << "fun2被调用" << endl;
}

int main()
{
	Event* e = new Event;
	Touch* t = new Touch;
	InputHandler* input=InputHandler::getInstance();

	/*类成员函数*/
	TestInput testInput;
	input += bind(&TestInput::fun1,testInput,placeholders::_2);
	
	/*仿函数对象*/
	TestFunctor testFunctor;
	input += bind(testFunctor,placeholders::_2);

	/*普通函数*/
	input += bind(fun2,placeholders::_2);

	/*lambda表达式*/
	input += [](Event* e,Touch* t){
		cout << "lambda表达式被调用" << endl;
	};

	input->onTouch(e,t);
	delete e;
	delete t;
	return 0;
}

Cocos2dx中常用的C++11特性的更多相关文章

  1. ios – 如何从变量访问属性或方法?

    是否可以使用变量作为Swift中方法或属性的名称来访问方法或属性?在PHP中,您可以使用$object->{$variable}.例如编辑:这是我正在使用的实际代码:解决方法你可以做到,但不能使用“纯粹的”Swift.Swift的重点是防止这种危险的动态属性访问.你必须使用Cocoa的Key-ValueCoding功能:非常方便,它完全穿过你要穿过的字符串到属性名称的桥,但要注意:这里是龙.

  2. iOS &gt;&gt;块&gt;&gt;更改块外部的变量值

    我不是在处理一个Object并改变它,就像我的mString一样.我希望’center’属性的行为类似于myInt,因为它是直接访问的C结构,而不是指向对象的指针.我希望’backgroundColor’的行为类似于我的imstring,因为它是一个指向一个新对象的对象的指针,不是吗?

  3. ios – Xcode Bot:如何在post触发器脚本上获得.ipa路径?

    我正在使用机器人来存档iOS应用程序,我需要获取.ipa产品路径才能将其发布到我们的分发系统中.机器人设置:并使用脚本打印所有env变量,其中不包含ipa文件的路径.此外,一些变量指向不存在的目录,即:XCS_OUTPUT_DIR这里的env变量输出:除此之外,我还能够确认.ipa文件是在另一个文件夹中创建的(/IntegrationAssets//

  4. ios – 使用附加字符串本地化Info.plist变量

    我正在尝试本地化应用程序的名称,同时仍然能够根据构建配置追加字符串.所以目前它被设置为:该设置定义为:通过这种方式,我们可以为应用程序添加后缀以用于不同的beta版本.问题是,当我们尝试本地化本地化的InfoPlist.strings中的应用程序显示名称时,就像这样我们覆盖存储在Info.plist中的值,并丢失后缀字符.这有什么好办法吗?

  5. iOS – 开始iOS教程 – 变量之前的下划线?

    这是正确的还是我做错了什么?

  6. ios – 静态计算变量被多次实例化

    我有一个日期格式化程序,我试图在UITableViewCell子类中创建一个单例,所以我创建了一个这样的计算属性:问题是我不止一次看到print语句,这意味着它不止一次被创建.我已经找到了其他方法,但我很想知道这里发生了什么.有任何想法吗?解决方法您的代码段相当于只获取属性,基本上它与以下内容相同:如果你只想运行一次,你应该像定义一个惰性属性一样定义它:

  7. ios – UIApplication.delegate必须仅在主线程中使用[复制]

    我应该在主调度中的viewControllers中声明这些)变量位置声明定义了它的范围.您需要确定这些变量的范围.您可以将它们声明为项目或应用程序级别(全局),类级别或特定此功能级别.如果要在其他ViewControllers中使用这些变量,则使用公共/开放/内部访问控制将其声明为全局或类级别.

  8. ios – 无法理解Objective-C块文档

    为什么localVariable“按价值使用?”>如果我在第二个例子中将__block存储类型添加到localVariable,我错误地假设该块关闭了变量,所以它将它保留在堆中直到块被释放?解决方法Howexactlyisoneexample“accessedbyreference”whiletheotheroneisaccessedbyvariable?self是当前正在执行找到块的方法的对象.强引用只是意味着对象的保留计数增加.IfIaddthe__blockstoragetypetolocalVar

  9. ios – 为BOOL变量编写getter和setter

    显然,使用obj-c,通常没有理由编写getter和setter(感谢有用的mr@synthesize).所以现在,需要做到这一点,我遇到了一个我不知道如何编写它们的问题.:p我敢肯定我可能不会以正确的方式解决我的问题–只是将我的对象子类化得更容易–但我正在尝试编写类别代码以添加属性,因为(在开头)它更快,因为我想学习如何在我的应用程序中使用类别代码.我有这个:我在setter中没有if查询就试过

  10. ios – 为什么不保留__block变量(在非ARC环境中)?

    我正在阅读__blockvariables上的文档,并考虑我使用__block的情况.对我来说,似乎我需要两种情况:>在块中使用时将变量标记为读写>在块内引用self时避免保留周期从表面上看,这两件事似乎并不相关.我认为__block变量没有被保留为更多的技巧我需要记住避免保留周期的特定用例.我想知道,为什么不能保留它们是否有更重要的建筑理由?

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部