cocos2d-x Vector&map&value

std::vector 和Vector不一样

后者是cocos封装的,必须是指针还必须是Ref类型

前者可以当数组使用

std::vector<int>  v1;
	int a=1;
	int b=2;

	v1.push_back(a);
	v1.push_back(b);
	
	
	CCLog("----value=%d",v1.at(1));
感觉好坑爹啊,这个容器自己研究了好久,还是没搞明白,在群里问人才知道,有个好的老师带领真好

转载的来源:百度

容器

3.0版本之前Cocos2d-x 引擎为我们提供了 CCArray、 CCDictionary 等 Objective-C 风格的容器;

使用 Cocos2d-x 容器的一个重要原因在于 Cocos2d-x 的内存管理。


一般来说,被存入容器的对象在移除之前都应该保证是有效的,

但值得注意的是,在v3.0 beta版本中加入了数据结构Vector。

定义在“cocos/base”的"CCVector.h"头文件中。

template<class T>class CC_DLL Vector;  


cocos2d::Vector<T>是一个封装好的能动态增长顺序访问的容器。

在cocos2d-x v3.0 beta之前,使用的是另外一个顺序访问容器cocos2d::CCArray,不过它将被废弃。

将采用cocos2d::Vector<T>来替代cocos2d::CCArray,

所以在后续的使用中,应该优先考虑使用cocos2d::Vector<T>。

Vector<T> 是Cocos2d-x 3.x推出的列表容器,因此它所能容纳的是Ref及子类所创建的对象指针,其中的T是模板,表示能够放入到容器中的类型,Cocos2d-x 3.x中T表示Ref。Vector<T>是模仿C++std::vector<T>模板类而设计的。在内存管理方面不使用__Array的引用计数,它的内存管理是由编译器自动处理的,可以不用考虑内存释放问题。Vector<T>的性能优于__Array类,Coco2d-x官方将Vector<T>设计为__Array的替代品,推荐使用Vector<T>类。

1、创建Vector对象

创建Vector对象有很多函数,下面是总结常用的函数:

 Vector()。默认的构造函数。

 Vector(ssize_t capacity)创建Vector对象,并设置容量。

 Vector(const Vector<T> &other) 。用一个已存在的Vector对象创建另一个Vector对象,其中&other是左值引用参数传递。

 Vector(Vector<T> &&other) 用一个已存在的Vector对象创建另一个Vector对象,其中&&other是右值引用参数传递。

 

提示  左值与右值?C++中所有的表达式和变量要么是左值,要么是右值。左值的定义就是非临时变量,可以在多条语句中使用的变量。右值是指临时的变量,它们只在当前的语句中有效。例如在语句int i = 0;中i为左值,0右值。左值与右值还可以出现在函数参数列表中,左值引用(&)和右值引用(&&),如下代码所示。

void process_value(int& i) {  //& i表示左值引用

  std::cout << "左值引用: " << i << std::endl; 

 

void process_value(int&& i) {   //&& i表示右值引用

  std::cout << "右值引用: " << i << std::endl; 

 

int main() { 

  int a = 0; 

  process_value(a);  //调用void process_value(int& i)函数

  process_value(1);  //调用void process_value(int&& i)函数

}

 

2、添加元素

向Vector对象中添加元素都必须是Ref对象指针类型,下面是总结常用的函数:

void pushBack(T object) 。添加一个元素,T表示Ref对象指针类型。

 void pushBack(const Vector<T> &other)把一个Vector对象中所有元素添加到当前Vector对象中。 

 void insert(ssize_t index, T object) 。在指定位置插入元素,ssize_tint类型别名

 

3、移除元素

下面是总结常用的移除Vector<T>容器中元素的函数:

void popBack()。移除最后一个元素。

 void eraseObject(T object, bool removeAll=false)。移除某个元素。 

iterator erase(iterator position)。指定位置移除对象,参数是迭代器,而返回值是下一个迭代器。

iterator erase(iterator first, iterator last)。指定移除对象范围(first~last),参数是迭代器,而返回值是下一个迭代器。

 iterator erase(ssize_t index)。移除一个指定索引的元素,参数是ssize_t,而返回值是下一个迭代器。

 void clear ()。移除所有元素。

 

4、替换和交换元素

我们还可以通过下面函数对Vector容器中元素替换和交换:

 void swap(T object1, T object2)。交换2个元素。 

 void swap(ssize_t index1, ssize_t index2)。交换2个指定位置元素。 

void replace(ssize_t index, T object)。用一个对象替代指定位置元素。

 

5、查找操作

我们有的时候还需要操作Vector中的元素,下面是总结常用的查找函数:

 iterator find (T object)。查找Vector容器中的对象,返回值迭代器。 

T at(ssize_t index)。根据索引位置返回Vector容器中的元素。

T front()。返回第一个元素。

T back ()。返回最后一个元素。

T getRandomObject()。返回随机元素。

bool contains(T object)。返回某个元素是否存在容器中。

ssize_t getIndex (T object)。返回指定对象的位置。

 

6、其它操作函数

此外还有很多操作Vector对象函数,下面是总结常用的函数:

ssize_t size ()。返回元素个数。 

ssize_t capacity()。返回Vector的容量。 



Vector的使用:

创建容器
1
Vector<Sprite*> sp_vec;

将创建好的精灵添加进容器中

1
2
3
4
5
auto sp1=Sprite::create( "CloseNormal.png" ); 
sp1->setPosition(Point(50,50));
this ->addChild(sp1); 
 
sp_vec.pushBack(sp1);

获得容器的大小
1
int count=sp_vec.size();

获得容器中的精灵,并让这些元素都做统一的动作
1
2
3
4
for ( auto& e : sp_vec) 
 
     e->runAction(MoveTo::create(0.2f,Point(200,200))); //这种for写法是C++ 11的新特性 
  }
 for (vector<PathSprite*>::iterator iter = m_openList.begin(); iter !=  m_openList.end(); iter++)  
            {  
                if ((*iter)->m_FValue < _sp->m_FValue)  
                {  
                    _sp = *iter;  
                }  
            }  


删除容器中的精灵
//如果是要删除容器中最后一个精灵:  sp_vec.popBack();  
//如果是直接删除对象      sp_vec.eraseObject(sp1);  
//如果是删除容器中全部的对象  sp_vec.clear();  

其他情况
//b 查找容器中的对象:  
//1、假设不知道容器中是否有sp3这个精灵,这时候可以这样:  
sp_vec.contains(sp3);//如果有,返回true;如果没有,返回false  
//2、已知容器中有sp3这个精灵,想获得它在容器中的位置:  
int pos_int=sp_vec.find(sp3);  
//上面的方法可以获得sp3的位置,但返回的其实是迭代器的地址,你得到的结果可能是45214等等,
如果想获得正常需要的位置,可以这样:  
int pos_int=sp_vec.find(sp3)-sp_vec.begin();  

除了加入Vector外,还加入了Map。
定义在"COCOS2DX_ROOT/cocos/base"的"CCMap.h"头文件中。

template <class K, class V>  
class CC_DLL Map;  
ocos2d::Map<K,V>是使用std::unordered_map作为底层结构的关联式容器。
而std::unordered_map是一个存储值对的关联式容器,它可以通过它们的键快速检索对应的值。
使用unordered_map,键通常是唯一的,而值则与这个键对应。

在unordered_map内部,元素是无序,它们是根据键的哈希值来存取的,存取的时间复杂度是常量,超级快。

在cocos2d-x v3.0之前,使用的是另外一种顺序式容器cocos2d::CCDictionary,不过它很快将被废弃。

所以在以后的使用中,应该尽量使用cocos2d::Map而不是cocos::CCDictionary。


Map基本使用
创建容器
//建立一个关联容器map,第一个参数是string型的键,第二个参数是Sprite类的键值  
1
2
3
4
5
Map<std::string,Sprite*>sp_map; 
 
auto sp1=Sprite::create( "CloseNormal.png" ); 
sp1->setPosition(Point(100,100)); 
this ->addChild(sp1,1);

将对象放入到容器中
sp_map.insert("sp1",sp1);//将精灵放入容器中,第一个参数是key  
取出容器中的元素
因为map是键值对的集合,所以我们可以通过指定的键,来取出相对应的值。
auto sp=sp_map.at("sp1");//通过键值获得sp1  

其他功能
1
2
3
4
5
6
7
8
9
auto sp2=sp_map.at( "sp1" ); //通过key取出sp1 
sp_map.insert( "11" ,sp2); //再将sp1以三个key值的方式存入map 
sp_map.insert( "22" ,sp2); 
sp_map.insert( "33" ,sp2); 
auto _key=sp_map.keys(sp1); //获得sp1对应的key值
for ( const auto&e : _key) 
   CCLOG( "_key is %s" ,e.c_str()); //输出sp1对应的key值(有四个,分别是:sp1,11,22,33)
}


Map对象的元素是键值对,也就是说每个元素包含两部分:键以及由键关联的值。
这种键和键值组成一个pair类,它的first元素指向键,second元素则为元素。
1
2
3
4
5
auto find_sp = sp_map.find( "10" ); //通过find()查找key为“10”的pair类型。
auto sp3 = find_sp->second; //键对应的对象 
std::string find_str = find_sp->first; //键 
CCLOG( "sp6 key value is %s" ,find_str.c_str()); //打印出键 
sp4->runAction(MoveBy::create(0.3f,Point(200,0))); //让sp6做运动

容器存在的意义不仅仅局限于内存管理方面,因此我们应该尽量采用 Cocos2d-x 提供的容器类。

面向对象的思想是一切皆对象
当我们在使用基本数据类型int、float等等的时候有时候需要把他们当做对象,
例如在向容器中存放东西的时候就不能存放这些基本的数据类型,cocos2d-x 3.0提供了Value
这个东西就是将基本数据类型当做对象来用的,初始化的时候传入基本的数据类型就可以了,
原来2.x版本的CCInteger、CCFloat这些东西被废弃了。

//创建栈上的对象value,在构造函数中传入你要初始化的值,传入的值的类型可以是
 /*BYTE,INTEGER,FLOAT,DOUBLE,BOOLEAN,STRING,VECTOR,MAP, INT_KEY_MAP*/

//创建栈上的对象value,在构造函数中传入你要初始化的值,传入的值的类型可以是
1
2
3
4
5
6
7
8
9
10
11
<pre name= "code" class = "cpp" >Value val1(5.21f);
Value val2( true );
 
//log的用法和CCLOG的相同,//getDescription是获得描述信息,返回值是string
log ( "val1' description is %s" ,val1.getDescription().c_str());.
log ( "val2' description is %s" ,val2.getDescription().c_str());
 
 
Value val3( "3" );
//as后边跟相应的数据类型可以转为相应的数据类型
log ( "val3 = %d" ,val3.asInt());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值