Cocos2dx 3.0 过渡篇(三十一)ValueVector和Vector不得不说的故事
本文投票地址:http://vote.blog.csdn.net/Article/Details?articleid=37834689
前天看到一个颇为纠结的选择题:有一天你遇到一个外星人,这时外星人非常热情的邀请你到他们星球去玩,你怎样选
1:去,可是你有可能永远不能在回来。
2:不去,可是外星人会消去你的记忆
这问题非常刺激有木有?!看似简单的一个问题,不同的答案却隐藏着不同的含义。
------------------
鱼与熊掌不可兼得,相似这样的样例生活中会经常碰到。相同的,假设你有去了解过Cocos2dx3.0,也会遇到这样一个令人纠结的情况:
那就是:Value 与 Vector(Map)。
为什么这么说呢?且听我慢慢道来。
-----------------
在Cocos2dx 2.0版本号,
我们要存储一个int型数据,应该放到哪里?没错,放到CCArray中,例如以下:
int i = 10;
CCArray _array = CCArray::create();//创建一个CCArray数组
_array->addObject(CCInteger::create(i));//将int型数据放入数组中
假设要存储一个CCObject对象,又是用什么存呢?是的,又是CCArray:
CCSprite* sp = CCSprite::create("star.png");//创建一个精灵
...
_array->addObject(sp);//将精灵放入到数组中
在Cocos2dx3.0版本号,
我们都知道该版本号的CCArray已经被甩了(实际上用__Array也还是能够替用一下),那么要存储一个Ref(3.0后CCObject改名为Ref)对象应该怎样操作?机智的我立即想到了CCArray的替代者:Vector,演示样例代码例如以下:
auto sp = Sprite::create("star.png");
...
Vector<Sprite*> sp_vec;//创建一个Sprite*类型的容器
sp_vec.pushBack(sp);//将精灵放入到容器中
假设对Vector的操作不是非常熟悉,能够看之前的博客:http://blog.csdn.net/star530/article/details/19170853
接下来问题来了,假设要存储一个数据类型,如int型数据,那么用Vector能够实现吗?答案是否定的,在Vector的官方说明文档里有这么一句话:
cocos2d::Vector<T> 中的T必须是一个指向cocos2d::Ref子类对象的指针。不能是其它数据类型或者原生类型,由于我们已经将 Cocos2d-x 的内存管理模型集成到 cocos2d::Vector<T> 中。
有句话叫什么来着:上帝为你关上了一扇门,一定会为你打开一扇窗...此处不留爷,自有留爷处...既然Vector容不下数据类型的元素,那么肯定有能够替代它的东西存在。没错,ValueVector登上了历史舞台。
第一次看到ValueVector时我就愣住了,这货又是什么碗糕?几秒后我反应过来,这货肯定是Value与Vector的私生子,我实在太特么机智了,这么抽象的命名都能让我高速想到答案,心中不禁暗自得意。
先到CCValue.h头文件里看下它的声明:
typedef std::vector<Value> ValueVector;
能够看出,ValueVector实际上就是一个存放Value类型元素的std::vector容器,这里和我之前的推測有些出入。以下将几个int型数据存储到ValueVector中。
int a = 10;
int b = 20;
ValueVector val_vec;
val_vec.push_back(Value(a));
val_vec.push_back(Value(b));
上面代码就是创建两个int型的变量,然后放入ValueVector中,当中要注意的是:由于ValueVector中仅仅能存放Value类型的元素,所以int型的a、b变量必须转换成Value类型后才干放入到ValueVector中。
关于Value的一些使用方法,能够看之前的博客:http://blog.csdn.net/star530/article/details/21651751
------------------------------------------------------------------------------------------------------------
说到ValueVector,那就顺便提下它的一些简单操作:
1、读取Plist(xml)配置文件。例如以下:
ValueVector star_val = FileUtils::getInstance()->getValueVectorFromFile("star.plist");
只是用ValueVector读取的plist文件仅仅局限于是该plist的格式的以array数组类型开头的,比如以下这样的:
<array>
<dict>
<key>name</key>
<string>star</string>
<key>isCool</key>
<string>yes</string>
</dict>
</array>
假设是以dict字典类型开头的文件,则要换用ValueMap,这是下一篇的内容,先跳过。
2、往ValueVector中插入一个元素。上面有提到过,ValueVector实际上就是一个存放Value类型的vector顺序容器,所以它的插入元素方式能够直接使用vector顺序容器的操作。示比例如以下:
int a = 10;
std::string b = "star is so cool";
ValueVector star_val;
star_val.push_back( Value(a) );
star_val.push_back( Value(b) );//放入ValueVector前都要先将类型转成Value类型
3、提取ValueVector中的元素。这里我接上面的样例来用:
int a1 = star_val.at(0).asInt();
std::string b1 = star_val.at(1).asString();
CCLOG("a1 = %d ,b1 = %s",a1,b1);
上面的代码比較easy理解,就是提取star_val中放在0和1位置上的元素,然后分别转成int型和string型。asInt()与asString()是Value用来实现类型转换的函数。
4、删除ValueVector中的元素。容器中比較经常使用的删除元素方式有三种:
1)删除容器中最后一个元素,
star_val.pop_back();//直接删除容器中最后一个元素
2)用erase删除容器中的某一个元素?为什么我要在前面加个问号呢?假设我要删除star_val中的 元素a,代码例如以下:
auto star_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)请收起手里愤慨的西瓜刀,深吸一口气。既然无法删除指定的元素,那我破罐子破摔,将所有元素都删除总能够吧?答案是肯定的:
star_val.clear();
用clear删除所有元素,从根源上解决您生理上的困扰~
-----------------------------------------------------------------------------------------------------------------------
好了,ValueVector的使用方法讲到这里,最后做下总结和补充:
1、Vector仅仅能用来存放Ref类型的元素,不能存放数据类型的元素;
2、ValueVector仅仅能用来存放Value类型的元素,由于Value说究竟就是数据类型,所以也能够觉得ValueVector仅仅能用来存放数据类型,千万别将Ref类型的元素放进入,否则会非常刺激。
3、ValueVector中能够放ValueVector,前提是将ValueVector转成Value类型;而Vector中不能存放Vector类型的元素,例如以下:
ValueVector star_val;
ValueVector star_val2;
star_val.push_back( Value(star_val2) );//正确 Vector< Vector<Ref*> > star_vec;//错误!
OK,就写到这里吧。
----------------------------------------------------------------------------------------------------------------------
尊重原创,转载请注明来源:http://blog.csdn.net/star530/article/details/37834689
本文參加了CSDN博客大赛,假设你觉得该篇对你有所帮助,请给我投上一票吧!我这辈子都会感激你的!投票地址:
http://vote.blog.csdn.net/Article/Details?articleid=37834689(拉倒页面最下方就可以投票)
Cocos2dx 3.0 过渡篇(三十一)ValueVector和Vector不得不说的故事的更多相关文章
- Cocos2dx 3.0 过渡篇(三十)灰机还是3D好(Sprite3D)
如今都非常少发3.0过渡篇这一系列的博文了,原因是多方面的,一个是游戏开发进度,尽管上面并没给我什么压力,但我自己一直在赶.还有一方面是个人私生活这块.五月份确实是多事之秋,有时候真的没办法全心思去研 ...
- Cocos2dx 3.0 过渡篇(二十六)C++11多线程std::thread的简单使用(上)
昨天练车时有一MM与我交替着练,聊了几句话就多了起来,我对她说:"看到前面那俩教练没?老色鬼两枚!整天调戏女学员."她说:"还好啦,这毕竟是他们的乐趣所在,你不认为教练每 ...
- Cocos2dx 3.0 过渡篇(二十八)C++11强类型枚举
一朋友在微信朋友圈晒了张照片,随手点开大图,带着赞赏的眼光扫了下,恩,几个月不见.又美丽了...咦?等等,她戴的这是什么?酷炫的造型! 金属边框! 微型摄像头! 这不是传说中的谷歌眼镜么?土豪啊,还好 ...
- Cocos2dx 3.0 过渡篇(二十九)globalZOrder()与localZOrder()
前天非常难得的加班到八点...为什么说难得呢?由于平时我差点儿就没加班过.六点下班后想走就走,想留就留.率直洒脱.不拘一格.尽显男儿本色.程序猿,就是这么自信! -----------这篇博客的标题本 ...
- Cocos2dx 3.0 过渡篇(二十五)死不了的贪食蛇(触摸版)
上一篇写的贪食蛇的重力感应控制版,这一篇就讲下触摸控制版吧.额,也不知道写了那个贪食蛇教程究竟有没有获得沈老师的书,假设没有的话,看我不拿西瓜刀砍掉 偶尔E往事 的那啥! 重力版链接:http://b ...
- Cocos2dx 3.0 过渡篇(二十七)C++11多线程std::thread的简单使用(下)
本篇接上篇继续讲:上篇传送门:http://blog.csdn.net/star530/article/details/24186783 简单的东西我都说的几乎相同了,想挖点深的差点把自己给填进去. ...
- 1、Cocos2dx 3.0游戏开发三找一小块前言
尊重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27094663 前言 Cocos2d-x 是一个通用 ...
- Cocos2dx 3.0 交流篇
创建项目: For(MAC) Runtime Requirements Android 2.3 or newer iOS 5.0 or newer OS X 10.7 or newer Windows ...
- Cocos2dx3.0过渡篇 globalZOrder()与localZOrder()
这篇博客的标题本想叫“...3.0新的渲染...介绍”,最后还是拉不下这个脸.为啥?觉得自己对渲染的认识还是过于表面,谈不上理解.当然了,这并不影响这篇博客继续写下去.下面看一段3.0Release ...
随机推荐
- Spring通过AOP实现对Redis的缓存同步
废话不多说 说下思路:使用aop注解,在Service实现类添加需要用到redis的方法上,当每次请求过来则对其进行拦截,如果是查询则从redis进行get key,如果是update则删除key,防 ...
- java笔记之数据类型
java中一句连续的字符不能分开在两行中书写,如国太长可用“+”将这两个字符串连起来 文档注释是以“/**”开头,并在注释内容末尾以“*/”结束. 文档注释是对代码的解释说明,可以使用javadoc命 ...
- Python之路Day5
一.时间复杂度 (1)时间频度: 一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费的时间就多.一个算法中的语句执行次数称为语句频度或时间频度,记为T(n). (2)时 ...
- python子进程模块subprocess调用shell命令
http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html
- Java 重入锁 ReentrantLock
本篇博客是转过来的. 但是略有改动感谢 http://my.oschina.net/noahxiao/blog/101558 摘要 从使用场景的角度出发来介绍对ReentrantLock的使用,相对来 ...
- Net FLow Template
EK Template : bool bfs(int src, int des){ memset(pre, -, sizeof(pre)); while(!que.empty()) que.pop( ...
- iOS开发笔记--使用blend改变图片颜色
最近对Core Animation和Core Graphics的内容东西比较感兴趣,自己之前也在这块相对薄弱,趁此机会也想补习一下这块的内容,所以之后几篇可能都会是对CA和CG学习的记录的文章. 在应 ...
- mul16
设计思想:乘法运算本身就可以看做是一个移位相加的过程 1 1 0 1 0 = 26* 1 0 1 1 1 = 23 ...
- 互联网创业十问?good(快速迭代、把握核心用户应对抄袭,不需要把商业模式考虑完备,4种失败的信号,失败者没资格说趁着年轻...)
著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:曹政链接:https://www.zhihu.com/question/20264499/answer/28168079来源: ...
- Android 代码设置密码输入框内容的显示/隐藏
//内容可见 mEtPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); //内容不可见 m ...