• 关于Cocos2d-x中数组的使用


    1.定义和背景

    cocos2d::Vector<T> 是一个封装了动态大小的数组的顺序型容器。

    它的元素是连续存储的,cocos2d::Vector<T> 的存储是自动处理的。其内部的数据结构实现实际上是STL标准的顺序型容器 std::vector。

    在 Cocos2d-x v3.0 beta 之前,存在另一个顺序性容器 cocos2d::CCArray,这将会被弃用。

    官方很细致地设计了 cocos2d::Vector<T> 容器作为 cocos2d::CCArray 的替代品,所以我们要使用 cocos2d::Vector<T> 代替 cocos2d::CCArray。这种数组的插入数据的方式和删除数据的方法有很多,而且也很灵活,既可以当表,也可以当栈

    2.数据类型

    T - 元素类型.
    -T 必须是一个指向 cocos2d::Object 子类对象的指针。不能是其他数据类型或者原生类型,因为Cocos2d-x 的内存管理模型已经集成到 cocos2d::Vector<T> 中(从 v3.0 beta 开始)。

    3.创建和释放

    _data 的内存管理是由编译器自动处理的。如果你在栈上声明了一个 cocos2d::Vector<T> 对象,那就不需要关心内存释放问题。

    如果你调用了 new 操作符来分配一块 cocos2d::Vector<T> 的动态内存,那就需要在使用完后调用 delete 操作符来释放内存。这同样适用于 new[] 和 delete[]。

    注意:在新 C++ 中,它倾向于本地存储对象而不是堆存储对象。所以,请不要调用 new 操作符来分配 cocos2d::Vector<T> 的堆对象,而是使用栈对象来代替它。
     
     
     

    4.具体用法

    //用一个容量初始化一个 vector 

    Vector<Sprite*>  vec1(5); 

    //定义一个数组要在HelloWorld类的属性中定义,语法是Vector<某个对象的类名*> 数组名;

    Vector<GameController*> gcs;

    //在一个确定的位置插入一个确定的对象(这里是在位置0插入一个Sprite类型的sp1变量指针)

    vec1.insert(0, sp1); 

    //我们也可以加入一整个 vector 

    vec1.pushBack(*vec0); 

    //从 vector 中移除元素 

    1.vec1.erase(vec1.find(sp0));  //sp0是一个对象实例,可以是节点,精灵或者其他一些数据类型

    2.pVec1->erase(1); //下标为1的变量

    3.pVec1->eraseObject(sp0,true);  //sp0是一个对象实例,可以是节点,精灵或者其他一些数据类型,这个方法在移除一个元素后,其他元素的位置就会发生变化,比如

       auto it = lifes.begin();

    (*it)->removeFromParent();

    lifes.eraseObject((*it), true);

    移除后,原来在1号位的变量就变成0号位了,也就是lifes.begin();用这个方法可以做一个血量减少,爱心从右往左减少的效果

    4.pVec1->popBack(); 

    5.vec1.clear(); //移除所有元素 

    //其他用法

    //如果两个vector 相同的话返回真 

    if (vec0->equals(vec2)) { 

        log("pVec0 is equal to pVec2"); 

    //判断vector是否为空 

    if (!vec1.empty()) { 

        //获取 vector 的 capacity 和 size,要注意的是 capacity 并不一定等于 size 

        if (vec1.capacity() == vec1.size()) { 

            log("pVec1->capacity()==pVec1->size()"); 

        }else{ 

            vec1.shrinkToFit();   //收缩 vector 以便内存对应上元素的数量 

            log("pVec1->capacity()==%zd; pVec1->size()==%zd",vec1.capacity(),vec1.size()); 

        } 

        //pVec1->swap(0, 1);  //通过索引交换 vector 中的两个元素 

        vec1.swap(vec1.front(), vec1.back());  //通过值交换 vector 中的两个元素  

            if (vec2.contains(sp0)) {  //返回一个布尔值,用于指示该对象是否存在于 vector 中 

            log("The index of sp0 in pVec2 is %zd",vec2.getIndex(sp0)); 

        } 

    }

    5.遍历

    如果要遍历某个数组,要用到数组对象的begin()方法和end()方法,再定义一个指向各个具体对象的指针,这个指针值加1的时候,所指向的实例对象会后移一个,初始时让它指向第一个实例

    for (auto it = gcs.begin(); it != gcs.end(); it++) {
      (*it)->onUpdate();

    }

    注意:如果我们在插入数据的时候是每个都在0的位置插入的话

    pic.insert(0, pic1);

    pic.insert(0, pic2);

    pic.insert(0, pic3);

    pic.insert(0, pic4);

    那么各个变量在数组中的顺序是

    pic4--pic3---pic2---pic1

    所以遍历起来的话是pic4为pic.begin(),产生了一个倒序的效果,并不是因为数组是什么先进后出,那是错误的思维,这个数组的遍历还是老老实实按照从左往右从0下标位开始的顺序的。

    6.详解(*it)=sprite

    如果定义了auto sprite=Sprite::create();之类的精灵节点,那么在

    for (auto it = gcs.begin(); it != gcs.end(); it++) {
      (*it)->onUpdate();

    }

    中,(*it)=sprite,而不是it=sprite,所以it是一个指向精灵节点指针的指针

    1.     //从 vector 中移除元素 
    2.     vec1.erase(vec1.find(sp0)); 
    3.     //pVec1->erase(1); 
    4.     //pVec1->eraseObject(sp0,true); 
    5.     //pVec1->popBack(); 
    6.   
    7.     vec1.clear(); //移除所有元素 
  • 相关阅读:
    HDU 5313 bitset优化背包
    bzoj 2595 斯坦纳树
    COJ 1287 求匹配串在模式串中出现的次数
    HDU 5381 The sum of gcd
    POJ 1739
    HDU 3377 插头dp
    HDU 1693 二进制表示的简单插头dp
    HDU 5353
    URAL 1519 基础插头DP
    UVA 10294 等价类计数
  • 原文地址:https://www.cnblogs.com/HangZhe/p/5701860.html
Copyright © 2020-2023  润新知