cocos2d::Value
http://cn.cocos2d-x.org/article/index?type=cocos2d-x&url=/doc/cocos-docs-master/manual/framework/native/v3/data-structure/value/zh.md
cocos2d::Value
是许多基本类型(int
,float
,double
,bool
,unsigned char,char*
和std::string
)还有std::vector<Value>
,std::unordered_map<std::string,Value>
和std::unordered_map<int,Value>
这些类的包装类型。
你可以将上面提及的基本类放进cocos2d::Value
对象将它们转换成对应的类型,反之亦然。
注意:当处理基本类型和和容器时,请使用cocos2d::Vector<T>
,cocos2d::Map<K,V>
和cocos2d::Value
。
cocos2d::Value
的内存由它的析构函数来释放,所以使用cocos2d::Value
时请尽量用推荐的最佳做法。
注意:cocos2d::Value
不能像其它cocos2d类型一样使用retain/release和refcount内存管理
当要使用基本类型的聚合时,将基本类型包装成cocos2d::Value,然后将它们和模版容器cocos2d::Vector和cocos2d::Map联合使用。
实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
Value val;
// call the default constructor
if
(val.isNull()) {
log
(
"val is null"
);
}
else
{
std::string str =val.getDescription();
log
(
"The description of val0:%s"
,str.c_str());
}
//----------------------------------------------------
Value val1(65);
// initialize with a integer
//Value val1(3.4f); // initialize with a float value
//Value val1(3.5); // initialize with a double value
log
(
"The description of the integer value:%s"
,val1.getDescription().c_str());
log
(
"val1.asByte() = %c"
,val1.asByte());
//----------------------------------------------------
std::string strV =
"string"
;
Value val2(strV);
// initialize with string
log
(
"The description of the string value:%s"
,val2.getDescription().c_str());
//----------------------------------------------------
auto sp0 = Sprite::create();
Vector<Object*>* vecV =
new
Vector<Object*>();
vecV->pushBack(sp0);
Value val3(vecV);
// initialize with Vector
log
(
"The description of the Vector value:%s"
,val3.getDescription().c_str());
delete
vecV;
//----------------------------------------------------
Map<std::string, Object*>* mapV =
new
Map<std::string, Object*>();
mapV->insert(strV,sp0);
Value val4(mapV);
// initialize with Map
log
(
"The description of the Map value:%s"
,val4.getDescription().c_str());
delete
mapV;
//----------------------------------------------------
Value val6(&val4);
// initialize with Map
log
(
"The description of the Value-type value:%s"
,val6.getDescription().c_str());
//----------------------------------------------------
val2 = val1;
// assigning between 2 Value-type
log
(
"operator-> The description of val2:%s"
,val2.getDescription().c_str());
val2 = 4;
//assigning directly
log
(
"operator-> The description of val4:%s"
,val2.getDescription().c_str());
|
cocos2d::Vector
http://cn.cocos2d-x.org/article/index?type=cocos2d-x&url=/doc/cocos-docs-master/manual/framework/native/v3/data-structure/vector/zh.mdcocos2d::Vector<T>
为cocos2d::CCArray
的替代品
事件复杂度为:
- 随机访问,O(1)
- 将元素插入到尾部或者删除尾部的元素,O(1)
- 随机插入或删除, O(n)
内存管理:
cocos2d::Vector<T>
类只包含一个成员数据:
std::vector<T> _data;
_data
的内存管理是由编译器自动处理的
实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
//create Vector<Sprite*> with default size and add a sprite into it
auto sp0 = Sprite::create();
sp0->setTag(0);
//here we use shared_ptr just as a demo. in your code, please use stack object instead
std::shared_ptr<Vector<Sprite*>> vec0 = std::make_shared<Vector<Sprite*>>();
//default constructor
vec0->pushBack(sp0);
//create a Vector<Object*> with a capacity of 5 and add a sprite into it
auto sp1 = Sprite::create();
sp1->setTag(1);
//initialize a vector with a capacity
Vector<Sprite*> vec1(5);
//insert a certain object at a certain index
vec1.insert(0, sp1);
//we can also add a whole vector
vec1.pushBack(*vec0);
for
(auto sp : vec1)
{
log
(
"sprite tag = %d"
, sp->getTag());
}
Vector<Sprite*> vec2(*vec0);
if
(vec0->equals(vec2)) {
//returns true if the two vectors are equal
log
(
"pVec0 is equal to pVec2"
);
}
if
(!vec1.empty()) {
//whether the Vector is empty
//get the capacity and size of the Vector, noted that the capacity is not necessarily equal to the vector size.
if
(vec1.capacity() == vec1.size()) {
log
(
"pVec1->capacity()==pVec1->size()"
);
}
else
{
vec1.shrinkToFit();
//shrinks the vector so the memory footprint corresponds with the number of items
log
(
"pVec1->capacity()==%zd; pVec1->size()==%zd"
,vec1.capacity(),vec1.size());
}
//pVec1->swap(0, 1); //swap two elements in Vector by their index
vec1.swap(vec1.front(), vec1.back());
//swap two elements in Vector by their value
if
(vec2.contains(sp0)) {
//returns a Boolean value that indicates whether object is present in vector
log
(
"The index of sp0 in pVec2 is %zd"
,vec2.getIndex(sp0));
}
//remove the element from the Vector
vec1.erase(vec1.find(sp0));
//pVec1->erase(1);
//pVec1->eraseObject(sp0,true);
//pVec1->popBack();
vec1.clear();
//remove all elements
log
(
"The size of pVec1 is %zd"
,vec1.size());
}
|
cocos2d::Map
http://cn.cocos2d-x.org/article/index?type=cocos2d-x&url=/doc/cocos-docs-master/manual/framework/native/v3/data-structure/map/zh.mdcocos2d::Map<K,V>
是使用std::unordered_map
作为底层结构的关联式容器。
在unordered_map内部,元素是无序,它们是根据键的哈希值来存取的,存取的时间复杂度是常量,超级快。
在Cocos2d-x v3.0beta之前,使用的是另外一种顺序式容器cocos2d::CCDictionary
,不过它将很快被废弃。
设计者们谨慎地设计了cocos2d::Map<K,V>
用来替代cocos2d::CCDictionary
,所以应该尽量使用cocos2d::Map
而不是cocos2d::CCDictionary
模板参数:
cocos2d::Map<K,V>
类只包含一个数据成员:
typedef
std::unordered_map<K, V> RefMap;
RefMap _data;
_data
的内存管理是由编译器处理的
,当在栈中声明
cocos2d::Map<K,V>
对象时,无需费心释放它占用的内存。 但是如果你是使用
new
操作来动态分配
cocos2d::Map<K,V>
的内存的话,就得用
delete
来释放内存了,
new[]
操作也一样。
实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
//create Map<K, V> with default size and add a sprite into it
auto sp0 = Sprite::create();
sp0->setTag(0);
Map<std::string, Sprite*> map0;
std::string mapKey0 =
"MAP_KEY_0"
;
map0.insert(mapKey0, sp0);
log
(
"The size of map is %zd."
,map0.size());
//create a Map<K, V> with capacity equals 5
Map<std::string, Sprite*> map1(map0);
std::string mapKey1 =
"MAP_KEY_1"
;
if
(!map1.empty()){
auto spTemp = (Sprite*)map1.at(mapKey0);
log
(
"sprite tag = %d"
, spTemp->getTag());
auto sp1 = Sprite::create();
sp1->setTag(1);
map1.insert(mapKey1, sp1);
//get all keys,stored in std::vector, that matches the object
std::vector<std::string> mapKeyVec;
mapKeyVec = map1.keys();
for
(auto key : mapKeyVec)
{
auto spTag = map1.at(key)->getTag();
log
(
"The Sprite tag = %d, MAP key = %s"
,spTag,key.c_str());
log
(
"Element with key %s is located in bucket %zd"
,key.c_str(),map1.bucket(key));
}
log
(
"%zd buckets in the Map container"
,map1.bucketCount());
log
(
"%zd element in bucket 1"
,map1.bucketSize(1));
//get a random object if the map isn't empty, otherwise it returns nullptr
log
(
"The random object tag = %d"
,map1.getRandomObject()->getTag());
//find(const K& key) can be used to search the container for an element with 'key'
//erase(const_iterator position) remove an element with an iterator
log
(
"Before remove sp0, size of map is %zd."
,map1.size());
map1.erase(map1.find(mapKey0));
log
(
"After remove sp0, size of map is %zd."
,map1.size());
}
//create a Map<K, V> with capacity equals 5
Map<std::string, Sprite*> map2(5);
map2.reserve(10);
//set capacity of the map
|
结果是:
1
2
3
4
5
6
7
8
9
10
11
|
cocos2d: The size of map is 1.
cocos2d: sprite tag = 0
cocos2d: The Sprite tag = 1, MAP key = MAP_KEY_1
cocos2d: Element with key MAP_KEY_1 is located in bucket 1
cocos2d: The Sprite tag = 0, MAP key = MAP_KEY_0
cocos2d: Element with key MAP_KEY_0 is located in bucket 0
cocos2d: 2 buckets in the Map container
cocos2d: 1 element in bucket 1
cocos2d: The random object tag = 0
cocos2d: Before
remove
sp0, size of map is 2.
cocos2d: After
remove
sp0, size of map is 1.
|