Cocos2dx 3.0 过渡篇(三十一)ValueVector和Vector不得不说的故事

Cocos2dx 3.0 过渡篇(三十一)ValueVector和Vector不得不说的故事,第1张

概述本文投票地址:http://vote.blog.csdn.net/Article/Details?articleid=37834689 前天看到一个颇为纠结的选择题:有一天你遇到一个外星人,这时外星人很热情的邀请你到他们星球去玩,你如何选 1:去,但是你有可能永远不能在回来。 2:不去,但是外星人会消去你的记忆 这问题很刺激有木有?! 看似简单的一个问题,不同的答案却隐藏着不同的含义。 -----

本文投票地址:http://vote.blog.csdn.net/Article/Details?articleid=37834689

前天看到一个颇为纠结的选择题:有一天你遇到一个外星人,这时外星人很热情的邀请你到他们星球去玩,你如何选

1:去,但是你有可能永远不能在回来。
2:不去,但是外星人会消去你的记忆

这问题很刺激有木有?! 看似简单的一个问题,不同的答案却隐藏着不同的含义。
------------------
鱼与熊掌不可兼得,类似这种例子生活中会经常碰到。同样的,如果你有去了解过Cocos2dx3.0,也会遇到这样一个令人纠结的情况:
那就是: Value 与 Vector(Map)。
为什么这么说呢?且听我慢慢道来。
-----------------

在Cocos2dx 2.0版本,
我们要存储一个int型数据,应该放到哪里?没错,放到 CCArray 中,如下:
[cpp] view plain copy inti=10; CCArray_array=CCArray::create();//创建一个CCArray数组 _array->addobject(CCInteger::create(i));//将int型数据放入数组中 如果要存储一个CCObject对象,又是用什么存呢?是的,又是
copy CCSprite*sp=CCSprite::create("star.png");//创建一个精灵 ... _array->addobject(sp);//将精灵放入到数组中
在Cocos2dx3.0版本,
我们都知道该版本的 CCArray已经被甩了 (实际上用 __Array 也还是可以替用一下),那么要存储一个Ref( 3.0后CCObject改名为Ref )对象应该如何 *** 作?机智的我马上想到了 CCArray的替代者:Vector ,示例代码如下:
copy autosp=Sprite::create("star.png"); Vector<Sprite*>sp_vec;//创建一个Sprite*类型的容器 sp_vec.pushBack(sp);//将精灵放入到容器中 如果对Vector的 *** 作不是很熟悉,可以看之前的博客:http://www.jb51.cc/article/p-olppyeev-bcy.html
接下来问题来了,如果要存储一个数据类型,如int型数据,那么用Vector可以实现吗?答案是否定的,在Vector的官方说明文档里有这么一句话:

cocos2d::Vector<T> 中的T必须是一个指向cocos2d::Ref子类对象的指针。不能是其他数据类型或者原生类型,因为我们已经将 Cocos2d-x 的内存管理模型集成到 cocos2d::Vector<T> 中。
有句话叫什么来着: 上帝为你关上了一扇门,一定会为你打开一扇窗...此处不留爷,自有留爷处... 既然Vector容不下数据类型的元素,那么肯定有可以替代它的东西存在。没错, ValueVector 登上了历史舞台。
第一次看到ValueVector时我就愣住了,这货又是什么碗糕?几秒后我反应过来,这货肯定是Value与Vector的私生子,我实在太特么机智了,这么抽象的命名都能让我快速想到答案,心中不禁暗自得意。
先到CCValue.h头文件中看下它的声明:
copy typedefstd::vector<Value>ValueVector; 可以看出, ValueVector实际上就是一个存放Value类型元素的std::vector容器 ,这里和我之前的猜测有些出入。下面将几个int型数据存储到ValueVector中。
copy
inta=10; intb=20; ValueVectorval_vec; val_vec.push_back(Value(a)); val_vec.push_back(Value(b));

上面代码就是创建两个int型的变量,然后放入ValueVector中,其中要注意的是:因为ValueVector中只能存放Value类型的元素,所以int型的a、b变量必须转换成Value类型后才能放入到ValueVector中。

关于Value的一些用法,可以看之前的博客:http://www.jb51.cc/article/p-dberlupz-bcy.html

------------------------------------------------------------------------------------------------------------

说到ValueVector,那就顺便提下它的一些简单 *** 作:
1、读取PList(xml)配置文件
。如下:
copy ValueVectorstar_val=FileUtils::getInstance()->getValueVectorFromFile("star.plist"); 不过用 ValueVector读取的plist文件只局限于是该plist的格式的以array数组类型开头的 ,例如下面这种:
[html] copy <array> dict> key>name</string>star>isCool>yes> 如果是以dict字典类型开头的文件,则要换用ValueMap,这是下一篇的内容,先跳过
2、往ValueVector中插入一个元素。 上面有提到过,ValueVector实际上就是一个存放Value类型的vector顺序容器,所以它的 插入元素方式可以直接使用vector顺序容器的 *** 作 。示例如下:
copy std::stringb="starissocool"; ValueVectorstar_val; star_val.push_back(Value(a)); star_val.push_back(Value(b));//放入ValueVector前都要先将类型转成Value类型
3、提取ValueVector中的元素。
这里我接上面的例子来用:
copy inta1=star_val.at(0).asInt(); std::stringb1=star_val.at(1).asString(); CCLOG("a1=%d,b1=%s",a1,b1); 上面的代码比较容易理解,就是 提取star_val中放在0和1位置上的元素,然后分别转成int型和string型。asInt()与asString()是Value用来实现类型转换的函数

4、删除ValueVector中的元素。
容器中比较常用的删除元素方式有三种:
1)删除容器中最后一个元素
copy star_val.pop_back();//直接删除容器中最后一个元素 2)用erase删除容器中的某一个元素? 为什么我要在前面加个问号呢?假设我要删除star_val中的 元素a,代码如下:
copy
autostar_iter=std::find(star_val.begin(),star_val.end(),a); star_val.erase(star_iter); 上面两行代码信息量还是比较大的,首先我们要知道erase 删除的是由一个迭代器指向的单个元素,而不是直接这样:
star_val.erase(a);

这种 *** 作是错误的,那么,什么是迭代器呢?我举个小例子:


假设一个教室就是一个vector容器,每个学生都是vector中的一个元素,而学生对应的座号就是迭代器。假设有一个新来的老师erase,她上课的时候你竟然和旁边的女同学眉来眼去,老师大怒,她打算让你立马从教室中滚出去,但她根本不知道你的名字,所以她只能这样做:

“第3列、第5排那个搞小动作的童鞋......别指了,说的就是你,你特么给我滚出去”


好了,让我们忘记这个麻辣女老师吧。既然已经知道erase里的参数须是一个迭代器,那么a元素对应的迭代器是什么呢? 这里就要用到find算法,它将返回a在容器中的迭代器。(std::find的具体用法请猛戳这里:点我!!!
最后, 我不得不羞涩的告诉大家,这种删除元素的方式是无法编译成功的!!!因为Value里没有重载==运算符,而std::find里面的数据类型必须实现==运算符,所以没法用查找,也就没法删除。
看到这里有人肯定要拍桌子了:尼玛,这方法不能删除你写这么多干嘛?裤子都脱了你就给我看这个?&……%*。
我的回答是: 呵呵...知道我当初折腾这个erase用了多少时间么?没错!我现在就是报复社会的节奏!不拿你们乐呵乐呵偶心里不痛快~!

3)请收起手里愤怒的西瓜刀,深吸一口气。
既然无法删除指定的元素,那我破罐子破摔,将全部元素都删除总可以吧?答案是肯定的:
copy star_val.clear(); 用clear删除全部元素,从根源上解决您生理上的困扰~

-----------------------------------------------------------------------------------------------------------------------

好了,ValueVector的用法说到这里,最后做下总结和补充:
1、Vector只能用来存放Ref类型的元素,不能存放数据类型的元素;
2、ValueVector只能用来存放Value类型的元素,因为Value说到底就是数据类型,所以也可以认为ValueVector只能用来存放数据类型,千万别将Ref类型的元素放进入,否则会很刺激。
3、ValueVector中可以放ValueVector,前提是将ValueVector转成Value类型;而Vector中不能存放Vector类型的元素,如下:

copy
ValueVectorstar_val; ValueVectorstar_val2; star_val.push_back(Value(star_val2));//正确 Vector<Vector<Ref*>>star_vec;//错误!

OK,就写到这里吧。

----------------------------------------------------------------------------------------------------------------------

尊重原创,转载请注明来源:http://www.jb51.cc/article/p-merduxpk-bcy.html
本文参加了CSDN博客大赛,如果你觉得该篇对你有所帮助,请给我投上一票吧!我这辈子都会感激你的!投票地址:

http://vote.blog.csdn.net/Article/Details?articleid=37834689(拉倒页面最下方即可投票)




FROM: http://blog.csdn.net/star530/article/details/37834689

总结

以上是内存溢出为你收集整理的Cocos2dx 3.0 过渡篇(三十一)ValueVector和Vector不得不说的故事全部内容,希望文章能够帮你解决Cocos2dx 3.0 过渡篇(三十一)ValueVector和Vector不得不说的故事所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1078427.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存