兄弟连Cocos2d-x教程12-Vector&map&value

在做Cocos2d-x2.0人的人们估计正在使用CCArray,CCDirectionary,CCDouble,CCFloat这些正搞得很爽,但不得不说

它们在V3.0中不用了。

看下3.0中的数据结合类Vector,Map,Value(建议大家自行阅读源码,本文只介绍如何使用,关于引用计数的概念推荐大家看我的视频),

以下案例来自TestCpp:

void TemplateVectorTest::onEnter()

{

UnitTestDemo::onEnter();

Vector<Node*> vec;//定义一个向量,其实是对stl Vector的封装,只是加入了对象的内存计数管理

CCASSERT(vec.empty(), "");

CCASSERT(vec.capacity() == 0, "");

CCASSERT(vec.size() == 0, "");

CCASSERT(vec.max_size() > 0, "");

auto node1 = Node::create();

node1->setTag(1);

vec.pushBack(node1);//在向量添加一个元素

CCASSERT(node1->getReferenceCount() == 2, "");

auto node2 = Node::create();

node2->setTag(2);

vec.pushBack(node2);//添加元素 编号会从0开始

CCASSERT(vec.getIndex(node1) == 0, "");

CCASSERT(vec.getIndex(node2) == 1, "");

auto node3 = Node::create();

node3->setTag(3);

vec.insert(1, node3); //插入元素

CCASSERT(vec.at(0)->getTag() == 1, "");

CCASSERT(vec.at(1)->getTag() == 3, "");

CCASSERT(vec.at(2)->getTag() == 2, "");

// Test copy constructor

Vector<Node*> vec2(vec); //复制一个向量

CCASSERT(vec2.size() == vec.size(), "");

ssize_t size = vec.size();

for (ssize_t i = 0; i < size; ++i)

{

CCASSERT(vec2.at(i) == vec.at(i), "");

CCASSERT(vec.at(i)->getReferenceCount() == 3, "");

CCASSERT(vec2.at(i)->getReferenceCount() == 3, "");

}

// Test copy assignment operator

Vector<Node*> vec3;

vec3 = vec2;

CCASSERT(vec3.size() == vec2.size(), "");

size = vec3.size();

for (ssize_t i = 0; i < size; ++i)

{

CCASSERT(vec3.at(i) == vec2.at(i), "");

CCASSERT(vec3.at(i)->getReferenceCount() == 4, "");

CCASSERT(vec2.at(i)->getReferenceCount() == 4, "");

CCASSERT(vec.at(i)->getReferenceCount() == 4, "");

}

// Test move constructor (Lambda 表达式,定义一个函数用于创建一个Vector,关于Lambda建议看我的视频)

auto createVector = [this](){

Vector<Node*> ret;

for (int i = 0; i < 20; i++)

{

ret.pushBack(Node::create());

}

int j = 1000;

for (auto& child : ret)

{

child->setTag(j++);

}

return ret;

};

Vector<Node*> vec4(createVector());

for (const auto& child : vec4)

{

CC_UNUSED_PARAM(child);

CCASSERT(child->getReferenceCount() == 2, "");

}

// Test init Vector<T> with capacity

Vector<Node*> vec5(10);

CCASSERT(vec5.capacity() == 10, "");

vec5.reserve(20);

CCASSERT(vec5.capacity() == 20, "");

CCASSERT(vec5.size() == 0, "");

CCASSERT(vec5.empty(), "");

auto toRemovedNode = Node::create();

vec5.pushBack(toRemovedNode);

CCASSERT(toRemovedNode->getReferenceCount() == 2, "");

// Test move assignment operator

vec5 = createVector();

CCASSERT(toRemovedNode->getReferenceCount() == 1, "");

CCASSERT(vec5.size() == 20, "size should be 20");

for (const auto& child : vec5) //这也是C++11新特性,好用吧,不像STL用迭代器那么麻烦

{

CC_UNUSED_PARAM(child);

CCASSERT(child->getReferenceCount() == 2, "");

}

// Test Vector<T>::find

CCASSERT(vec.find(node3) == (vec.begin() + 1), "");

CCASSERT(std::find(std::begin(vec), std::end(vec), node2) == (vec.begin() + 2), "");

CCASSERT(vec.front()->getTag() == 1, "");

CCASSERT(vec.back()->getTag() == 2, "");

CCASSERT(vec.getRandomObject(), "");

CCASSERT(!vec.contains(Node::create()), "");

CCASSERT(vec.contains(node1), "");

CCASSERT(vec.contains(node2), "");

CCASSERT(vec.contains(node3), "");

CCASSERT(vec.equals(vec2), "");

CCASSERT(vec.equals(vec3), "");

// Insert

vec5.insert(2, node1);

CCASSERT(vec5.at(2)->getTag() == 1, "");

CCASSERT(vec5.size() == 21, "");

vec5.back()->setTag(100);

vec5.popBack();

CCASSERT(vec5.size() == 20, "");

CCASSERT(vec5.back()->getTag() != 100, "");

// Erase and clear

Vector<Node*> vec6 = createVector();

Vector<Node*> vec7 = vec6; // Copy for check

CCASSERT(vec6.size() == 20, "");

vec6.erase(vec6.begin() + 1); //

CCASSERT(vec6.size() == 19, "");

CCASSERT((*(vec6.begin() + 1))->getTag() == 1002, "");

vec6.erase(vec6.begin() + 2, vec6.begin() + 10);

CCASSERT(vec6.size() == 11, "");

CCASSERT(vec6.at(0)->getTag() == 1000, "");

CCASSERT(vec6.at(1)->getTag() == 1002, "");

CCASSERT(vec6.at(2)->getTag() == 1011, "");

CCASSERT(vec6.at(3)->getTag() == 1012, "");

vec6.erase(3);

CCASSERT(vec6.at(3)->getTag() == 1013, "");

vec6.eraseObject(vec6.at(2));

CCASSERT(vec6.at(2)->getTag() == 1013, "");

vec6.clear();

auto objA = Node::create(); // retain count is 1

auto objB = Node::create();

auto objC = Node::create();

{

Vector<Node*> array1;

Vector<Node*> array2;

// push back objA 3 times

array1.pushBack(objA); // retain count is 2

array1.pushBack(objA); // retain count is 3

array1.pushBack(objA); // retain count is 4

array2.pushBack(objA); // retain count is 5

array2.pushBack(objB);

array2.pushBack(objC);

for (auto obj : array1) {

array2.eraseObject(obj);

}

CCASSERT(objA->getReferenceCount() == 4, "");

}

CCASSERT(objA->getReferenceCount() == 1, "");

{ //这是一个代码块,出了块引用计数会恢复,是一个AutoReleasePool

Vector<Node*> array1;

// push back objA 3 times

array1.pushBack(objA); // retain count is 2

array1.pushBack(objA); // retain count is 3

array1.pushBack(objA); // retain count is 4

CCASSERT(objA->getReferenceCount() == 4, "");

array1.eraseObject(objA, true); // Remove all occurrences in the Vector.

CCASSERT(objA->getReferenceCount() == 1, "");

array1.pushBack(objA); // retain count is 2

array1.pushBack(objA); // retain count is 3

array1.pushBack(objA); // retain count is 4

array1.eraseObject(objA, false);

CCASSERT(objA->getReferenceCount() == 3, ""); // Only remove the first occurrence in the Vector.

}

// Check the retain count in vec7

CCASSERT(vec7.size() == 20, "");

for (const auto& child : vec7)

{

CC_UNUSED_PARAM(child);

CCASSERT(child->getReferenceCount() == 2, "");

}

// Sort 排序,结合Lambda

Vector<Node*> vecForSort = createVector();

std::sort(vecForSort.begin(), vecForSort.end(), [](Node* a, Node* b){

return a->getTag() >= b->getTag();

});

for (int i = 0; i < 20; ++i)

{

CCASSERT(vecForSort.at(i)->getTag() - 1000 == (19 - i), "");

}

// Reverse

vecForSort.reverse();

for (int i = 0; i < 20; ++i)

{

CCASSERT(vecForSort.at(i)->getTag() - 1000 == i, "");

}

// Swap

Vector<Node*> vecForSwap = createVector();

vecForSwap.swap(2, 4);

CCASSERT(vecForSwap.at(2)->getTag() == 1004, "");

CCASSERT(vecForSwap.at(4)->getTag() == 1002, "");

vecForSwap.swap(vecForSwap.at(2), vecForSwap.at(4));

CCASSERT(vecForSwap.at(2)->getTag() == 1002, "");

CCASSERT(vecForSwap.at(4)->getTag() == 1004, "");

// shrinkToFit

Vector<Node*> vecForShrink = createVector();

vecForShrink.reserve(100);

CCASSERT(vecForShrink.capacity() == 100, "");

vecForShrink.pushBack(Node::create());

vecForShrink.shrinkToFit();

CCASSERT(vecForShrink.capacity() == 21, "");

// get random object

// Set the seed by time

srand((unsigned)time(nullptr));

Vector<Node*> vecForRandom = createVector();

log("<--- begin ---->");

for (int i = 0; i < vecForRandom.size(); ++i)

{

log("Vector: random object tag = %d", vecForRandom.getRandomObject()->getTag());

}

log("<---- end ---->");

// Self assignment

Vector<Node*> vecSelfAssign = createVector();

vecSelfAssign = vecSelfAssign;

CCASSERT(vecSelfAssign.size() == 20, "");

for (const auto& child : vecSelfAssign)

{

CC_UNUSED_PARAM(child);

CCASSERT(child->getReferenceCount() == 2, "");

}

vecSelfAssign = std::move(vecSelfAssign);

CCASSERT(vecSelfAssign.size() == 20, "");

for (const auto& child : vecSelfAssign)

{

CC_UNUSED_PARAM(child);

CCASSERT(child->getReferenceCount() == 2, "");

}

// const at

Vector<Node*> vecConstAt = createVector();

constFunc(vecConstAt);

}

//---------------------------以下是Map的使用-----------------------------------

void TemplateMapTest::onEnter()

{

UnitTestDemo::onEnter();

auto createMap = [this](){

Map<std::string, Node*> ret;

for (int i = 0; i < 20; ++i)

{

auto node = Node::create();

node->setTag(1000 + i);

ret.insert(StringUtils::toString(i), node);

}

return ret;

};

// Default constructor

Map<std::string, Node*> map1;

CCASSERT(map1.empty(), "");

CCASSERT(map1.size() == 0, "");

CCASSERT(map1.keys().empty(), "");

CCASSERT(map1.keys(Node::create()).empty(), "");

// Move constructor

Map<std::string, Node*> map2 = createMap();

for (const auto& e : map2)

{

CC_UNUSED_PARAM(e);

CCASSERT(e.second->getReferenceCount() == 2, "");

}

// Copy constructor

Map<std::string, Node*> map3(map2);

for (const auto& e : map3)

{

CC_UNUSED_PARAM(e);

CCASSERT(e.second->getReferenceCount() == 3, "");

}

// Move assignment operator

Map<std::string, Node*> map4;

auto unusedNode = Node::create();

map4.insert("unused",unusedNode);

map4 = createMap();

CCASSERT(unusedNode->getReferenceCount() == 1, "");

for (const auto& e : map4)

{

CC_UNUSED_PARAM(e);

CCASSERT(e.second->getReferenceCount() == 2, "");

}

// Copy assignment operator

Map<std::string, Node*> map5;

map5 = map4;

for (const auto& e : map5)

{

CC_UNUSED_PARAM(e);

CCASSERT(e.second->getReferenceCount() == 3, "");

}

// Check size

CCASSERT(map4.size() == map5.size(), "");

for (const auto& e : map4)

{

CC_UNUSED_PARAM(e);

CCASSERT(e.second == map5.find(e.first)->second, "");

}

// bucket_count, bucket_size(n), bucket

log("--------------");

log("bucket_count = %d", static_cast<int>(map4.bucketCount()));

log("size = %d", static_cast<int>(map4.size()));

for (int i = 0; i < map4.bucketCount(); ++i)

{

log("bucket_size(%d) = %d", i, static_cast<int>(map4.bucketSize(i)));

}

for (const auto& e : map4)

{

log("bucket(\"%s\"), bucket index = %d", e.first.c_str(), static_cast<int>(map4.bucket(e.first)));

}

log("----- all keys---------");

// keys and at

auto keys = map4.keys();

for (const auto& key : keys)

{

log("key = %s", key.c_str());

}

auto node10Key = map4.at("10");

map4.insert("100", node10Key);

map4.insert("101", node10Key);

map4.insert("102", node10Key);

log("------ keys for object --------");

auto keysForObject = map4.keys(node10Key);

for (const auto& key : keysForObject)

{

log("key = %s", key.c_str());

}

log("--------------");

// at in const function

constFunc(map4);

// find

auto nodeToFind = map4.find("10");

CC_UNUSED_PARAM(nodeToFind);

CCASSERT(nodeToFind->second->getTag() == 1010, "");

// insert

Map<std::string, Node*> map6;

auto node1 = Node::create();

node1->setTag(101);

auto node2 = Node::create();

node2->setTag(102);

auto node3 = Node::create();

node3->setTag(103);

map6.insert("insert01", node1);

map6.insert("insert02", node2);

map6.insert("insert03", node3);

CCASSERT(node1->getReferenceCount() == 2, "");

CCASSERT(node2->getReferenceCount() == 2, "");

CCASSERT(node3->getReferenceCount() == 2, "");

CCASSERT(map6.at("insert01") == node1, "");

CCASSERT(map6.at("insert02") == node2, "");

CCASSERT(map6.at("insert03") == node3, "");

// erase

Map<std::string, Node*> mapForErase = createMap();

mapForErase.erase(mapForErase.find("9"));

CCASSERT(mapForErase.find("9") == mapForErase.end(), "");

CCASSERT(mapForErase.size() == 19, "");

mapForErase.erase("7");

CCASSERT(mapForErase.find("7") == mapForErase.end(), "");

CCASSERT(mapForErase.size() == 18, "");

std::vector<std::string> itemsToRemove;

itemsToRemove.push_back("2");

itemsToRemove.push_back("3");

itemsToRemove.push_back("4");

mapForErase.erase(itemsToRemove);

CCASSERT(mapForErase.size() == 15, "");

// clear

Map<std::string, Node*> mapForClear = createMap();

auto mapForClearCopy = mapForClear;

mapForClear.clear();

for (const auto& e : mapForClearCopy)

{

CC_UNUSED_PARAM(e);

CCASSERT(e.second->getReferenceCount() == 2, "");

}

// get random object

// Set the seed by time

srand((unsigned)time(nullptr));

Map<std::string, Node*> mapForRandom = createMap();

log("<--- begin ---->");

for (int i = 0; i < mapForRandom.size(); ++i)

{

log("Map: random object tag = %d", mapForRandom.getRandomObject()->getTag());

}

log("<---- end ---->");

// Self assignment

Map<std::string, Node*> mapForSelfAssign = createMap();

mapForSelfAssign = mapForSelfAssign;

CCASSERT(mapForSelfAssign.size() == 20, "");

for (const auto& e : mapForSelfAssign)

{

CC_UNUSED_PARAM(e);

CCASSERT(e.second->getReferenceCount() == 2, "");

}

mapForSelfAssign = std::move(mapForSelfAssign);

CCASSERT(mapForSelfAssign.size() == 20, "");

for (const auto& e : mapForSelfAssign)

{

CC_UNUSED_PARAM(e);

CCASSERT(e.second->getReferenceCount() == 2, "");

}

}

//--------------------------以下是Value的使用,它完成基本数据类型到对象的包装--------

void ValueTest::onEnter()

{

UnitTestDemo::onEnter();

Value v1;

CCASSERT(v1.getType() == Value::Type::NONE, "");

CCASSERT(v1.isNull(), "");

Value v2(100);

CCASSERT(v2.getType() == Value::Type::INTEGER, "");

CCASSERT(!v2.isNull(), "");

Value v3(101.4f);

CCASSERT(v3.getType() == Value::Type::FLOAT, "");

CCASSERT(!v3.isNull(), "");

Value v4(106.1);

CCASSERT(v4.getType() == Value::Type::DOUBLE, "");

CCASSERT(!v4.isNull(), "");

unsigned char byte = 50;

Value v5(byte);

CCASSERT(v5.getType() == Value::Type::BYTE, "");

CCASSERT(!v5.isNull(), "");

Value v6(true);

CCASSERT(v6.getType() == Value::Type::BOOLEAN, "");

CCASSERT(!v6.isNull(), "");

Value v7("string");

CCASSERT(v7.getType() == Value::Type::STRING, "");

CCASSERT(!v7.isNull(), "");

Value v8(std::string("string2"));

CCASSERT(v8.getType() == Value::Type::STRING, "");

CCASSERT(!v8.isNull(), "");

auto createValueVector = [&](){

ValueVector ret;

ret.push_back(v1);

ret.push_back(v2);

ret.push_back(v3);

return ret;

};

Value v9(createValueVector());

CCASSERT(v9.getType() == Value::Type::VECTOR, "");

CCASSERT(!v9.isNull(), "");

auto createValueMap = [&](){

ValueMap ret;

ret["aaa"] = v1;

ret["bbb"] = v2;

ret["ccc"] = v3;

return ret;

};

Value v10(createValueMap());

CCASSERT(v10.getType() == Value::Type::MAP, "");

CCASSERT(!v10.isNull(), "");

auto createValueMapIntKey = [&](){

ValueMapIntKey ret;

ret[111] = v1;

ret[222] = v2;

ret[333] = v3;

return ret;

};

Value v11(createValueMapIntKey());

CCASSERT(v11.getType() == Value::Type::INT_KEY_MAP, "");

CCASSERT(!v11.isNull(), "");

}

----------------------------亲,学会了没----------------------------

原作者: 草莓vc

标签:教程, 兄弟
分类:电脑软件
时间:2014-06-15

兄弟连Cocos2d-x教程12-Vector&map&value的相关文章

iPhone5S省电教程 12种省电设置教给你

iPhone虽然作为市面上最出色的智能手机,但续航仍然不能够让人满意,可以说省电是许多用户的重中之重,今天就给大家带来iPhone5S省点教程,12种省电设置让你的iPhone5S电量更加持久!

CGCS2000坐标系投影转换教程12

CGCS2000坐标系投影转换教程注意:投影转换成cgcs2000坐标系需要下载无偏移卫星图像进行转换,有偏移的转换将导致转换后的卫星图像扭曲,坐标错误,无法配准。第一步:选择无偏移地图源,下载你所需要的卫星图像。第二步:选择BIGEMAP软件右边工具栏,选择【投影转换】,如下图所示:

多重曝光教程 12种人像和风光重曝叠加分析

多重曝光multiple exposure是摄影中一种采用两次或者更多次独立曝光,然后将它们重叠起来,组成单一照片的技术方法.由于其中各次曝光的参数不同,因此最后的照片会产生独特的视觉效果.多重曝光是一种拍摄技法,不过为了烘托气氛,常常选择这种技法,用不同焦距分两次或多次曝光来表现一张照片难以表现的内容.多重曝光技法独具魅力,拍摄双影或多影的影像,充满着魔术般无中生有的艺术效果,多重曝光有很多具体的结合,每一种重曝方式有着无限的创作空间.下面就以庞易的12张照片来重点剖析多重曝光的12种形式.

Latex教程: [12]插入特殊字符,插入日期

我们都知道Word里面有一个专门的特殊字符库可供用户插入,那么Latex里面如何插入特殊字符呢?这里我带大家了解一下如何在Latex里面插入特殊字符。

美化教程12:更换翻页符

本章思路源自Cydia的No Page Dots。就是下边分页的小点,这些小点就相当于页码。 如果你的图标超过了一页,那么下面就会显示这个提示符。你当前页的提示符是亮的,其它页暗一些。图片的大小是6相素见方。下面是正常的翻页提示符。

wp插件教程12:AG Custom Admin管理菜单定制

AG Custom Admin的功能真是强大哦,其实想想很多设置也就是替换数据库中的字段嘛,但是给人感觉很方便且牛逼,似乎可以给你的wp换装,不需要你懂编程写代码,多爽!这里教你用AG Custom Admin修改wordpress的菜单项目,这个玩好了可以装牛,其实还挺简单。x

枪火兄弟连2 Gun Bros2内购美金修改教程

上期攻略中我们介绍了枪火兄弟连2的游戏攻略,本期我们将为大家带来枪火兄弟连2修改教程,游戏中有两大货币系统,第一种货币为紫水晶,而第二种就是游戏中无法轻易获得的绿色游戏币了,这种高级游戏币可以购买更多顶级的武器装备,所以你懂的。

iPhone 4 iOS5.1.1 红雪RedSn0w 0.9.12b2完美越狱教程

教程说明:如何使用红雪工具(DFU模式)RedSn0w完美越狱iPhone 4(A4处理器设备均适用)5.1.1固件 本教程适用于无锁机,会自动升级基带到最新版。(注:无锁机包括港行,联通国行,以及通过其他渠道如Apple Store购买的不需解锁的无合约设备)。 有锁机用户请自制保基带固件参考pc6教程 用最新版Redsn0w恢复SAM解锁激活码,请参考图文教程 教程适用的设备 (iOS 4.1 to 5.1.1) iPhone 4 (GSM + CDMA) 和 iPh

Excel如何输入身份证号码动画教程

《Excel2003入门动画教程12、Excel如何输入身份证号码》。 演示动画 操作步骤 在Excel中,输入超过12位的数值,系统自动将其转换为科学记数格式,如果输入超过15位的数值,系统自动将15位以后的数值转换为“0”。这种转换对于我们需要输入一些特殊数值(如身份证号码)时,就不能符合我们的要求了。为了能让这些长位数数值完整显示出来,就必须用下面两种方法,将单元格转换成文本格式,然后再输入。 在输入这些长数值时,先输入一个英文状态下的单引号(“'”),然后接头输入数值即可