zoukankan      html  css  js  c++  java
  • cocos基础教程(5)数据结构介绍之cocos2d::Vector

    cocos2d::Vector

    cocos2d::Vector<T>是一个封装好的能动态增长顺序访问的容器。cocos2d::Vector<T>中的元素是按序存取的,它的低层实现数据结构是标准模版库中的标准顺序容器std::vector

    T - 元素类型

    • T的类型必须是继承自cocos2d::Object类型的指针。因为已经将Cocos2d-x的内存管理模型集成到了cocos2d::Vector<T>中,所以类型参数不能是其他的类型包括基本类型。

    注意:使用现代的c++,本地存储对象比堆存储对象好。所以请不要用new操作来申请cocos2d::Vector<T>的堆对象,请使用栈对象。

    警告cocos2d::Vector<T>并不是cocos2d::Object的子类,所以不要像使用其他cocos2d类一样来用retain/release和引用计数内存管理。

    用法:pushBack()操作将会保留传递过来的参数,而popBack()则会释放掉容器中最后的一个元素。cocos2d::Vector<T>并没有重载[]操作,所以不能直接用下标[i]来获取第i位元素。cocos2d::Vector<T>提供了不同类型的迭代器,我们可以使用大量标准泛型算法和for_each循环。如果你有足够的理由在堆上动态分配 cocos2d::Vector<T> 的话,请使用智能指针替换原始指针,比如 Shared_ptr,unique_ptr。

    这里提供一个简单的示例:

    //使用默认大小创建一个 Vector<Sprite*>,然后往其中加入一个精灵
    auto sp0 = Sprite::create();
    sp0->setTag(0);
    //这里我们 demo 使用了 shared_ptr,在你的代码中,请使用栈对象替代 
    std::shared_ptr<Vector<Sprite*>>  vec0 = std::make_shared<Vector<Sprite*>>();  //default constructor
    vec0->pushBack(sp0);
     
    //使用capacity为5来创建一个 Vector<Object*>,然后往其中加入一个精灵
    auto sp1 = Sprite::create();
    sp1->setTag(1);
     
    //用一个容量初始化一个 vector
    Vector<Sprite*>  vec1(5);
    //在一个确定的位置插入一个确定的对象
    vec1.insert(0, sp1);
     
    //我们也可以加入一整个 vector
    vec1.pushBack(*vec0);
     
    for(auto sp : vec1)
    {
        log("sprite tag = %d", sp->getTag());
    }
     
    Vector<Sprite*> vec2(*vec0);
    if (vec0->equals(vec2)) { //如果两个 vector 相同的话返回真
        log("pVec0 is equal to pVec2");
    }
    if (!vec1.empty()) {  //判断 vector 是否为空
        //获取 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));
        }
        //从 vector 中移除元素
        vec1.erase(vec1.find(sp0));
        //pVec1->erase(1);
        //pVec1->eraseObject(sp0,true);
        //pVec1->popBack();
     
        vec1.clear(); //移除所有元素
        log("The size of pVec1 is %zd",vec1.size());
    }

    输出结果

    Cocos2d: sprite tag = 1
    Cocos2d: sprite tag = 0
    Cocos2d: pVec0 is equal to pVec2
    Cocos2d: pVec1->capacity()==2; pVec1->size()==2
    Cocos2d: The index of sp0 in pVec2 is 0
    Cocos2d: The size of pVec1 is 0

    最佳实践

    • 偏向于使用基于栈构建的 cocos2d::Vector<T> 而不使用基于堆构建的 cocos2d::Vector<T>。
    • 当将 cocos2d::Vector<T> 作为参数进行传递的时候,将它声明为一个常引用,如 const cocos2d::Vector<T>&。
    • 当从一个函数中返回一个 cocos2d::Vector<T> 时,简单地返回值对象。编译器将使用移动语义优化这种情况。
    • 不要试图在 cocos2d::Vector<T> 中保存除 cocos2d::Object 子类对象指针以外的其他任意数据类型对象。
  • 相关阅读:
    表单实现仿淘宝搜索应用
    ASCII字符集
    HTTP状态码
    总结get和post区别
    总结Canvas和SVG的区别
    展示github中的页面(Github Pages)
    canvas的beginPath和closePath分析总结,包括多段弧的情况
    12. Integer to Roman
    13. Roman to Integer
    463. Island Perimeter
  • 原文地址:https://www.cnblogs.com/damowang/p/4810585.html
Copyright © 2011-2022 走看看