| 版权声明:本文为博主原创文章,未经博主允许不得转载。
Vector<T>是Cocos2d-x 3.x中推出的列表容器,在cocos2d-x3.0之前的版本是Array,因此它所能容纳的是Ref及子类所创建的对象指针,其中T是一个模板(也就是c++中的模板),表示能够放入到容器中的类型,在Cocos2d-x 3.x中T表示Ref类,其实Vector<T>就是模仿c++中的std::vector<T>模板类而来;Vector<T>的最大优点是可以自动的增大容器的大小,这比Array更好。cocos2d::Vector是一个封装好的能动态增长顺序的访问容器,cocos2d::Vector中的元素是按顺序存取的,它的底层实现数据结构是标准模板库中的标准顺序容器std::Vector中的元素是按顺序存取的,它的底层实现数据结构是标准模板库中的标准顺序容器std.
创建Vector对象的函数:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** Constructor. 默认的构造函数Vector()*/ 2 Vector<T>() 3 : _data() 4 { 5 static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!"); 6 } 7 /** Constructor with a capacity.param capacity Capacity of the Vector.创建Vector对象,并设置容量*/ 8 explicit Vector<T>(ssize_t capacity) 9 : _data() 10 { 11 static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!"); 12 CCLOGINFO("In the default constructor with capacity of Vector."); 13 reserve(capacity); 14 } 15 16 /** Copy constructor.用一个已经存在的Vector对象来创建另一个Vector对象,其中&other是左值引用参数传递 */ 17 Vector<T>(const Vector<T>& other) 18 { 19 static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!"); 20 CCLOGINFO("In the copy constructor!"); 21 _data = other._data; 22 addRefForAllObjects(); 23 } 24 /** Constructor with std::move semantic.用一个已经存在的Vector对象创建另一个Vector对象,其中&&other是右值引用参数传递*/ 25 Vector<T>(Vector<T>&& other) 26 { 27 static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!"); 28 CCLOGINFO("In the move constructor of Vector!"); 29 _data = std::move(other._data); 30 }
添加元素的函数:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 在Vector对象中添加元素都必须是Ref对象的指针类型。 2 3 /** Adds a new element at the end of the Vector. 添加一个元素,T表示Ref对象指针类型*/ 4 void pushBack(T object) 5 { 6 CCASSERT(object != nullptr, "The object should not be nullptr"); 7 _data.push_back( object ); 8 object->retain(); 9 } 10 /** Push all elements of an existing Vector to the end of current Vector. 把一个Vector对象中所有元素添加到当前的Vector对象中*/ 11 void pushBack(const Vector<T>& other) 12 { 13 for(const auto &obj : other) { 14 _data.push_back(obj); 15 obj->retain(); 16 } 17 } 18 /** Insert an object at certain index. @param index The index to be inserted at.@param object The object to be inserted.在指定的位置插入元素*/ 19 void insert(ssize_t index, T object) 20 { 21 CCASSERT(index >= 0 && index <= size(), "Invalid index!"); 22 CCASSERT(object != nullptr, "The object should not be nullptr"); 23 _data.insert((std::begin(_data) + index), object); 24 object->retain(); 25 }
移除元素常用的函数:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** Removes the last element in the Vector. 移除最后一个元素*/ 2 void popBack() 3 { 4 CCASSERT(!_data.empty(), "no objects added"); 5 auto last = _data.back(); 6 _data.pop_back(); 7 last->release(); 8 } 9 10 /** Remove a certain object in Vector.param object The object to be removed.param removeAll Whether to remove all elements with the same value.If its value is 'false', it will just erase the first occurrence. 移除某个元素*/ 11 void eraseObject(T object, bool removeAll = false) 12 { 13 CCASSERT(object != nullptr, "The object should not be nullptr"); 14 15 if (removeAll) 16 { 17 for (auto iter = _data.begin(); iter != _data.end();) 18 { 19 if ((*iter) == object) 20 { 21 iter = _data.erase(iter); 22 object->release(); 23 } 24 else 25 { 26 ++iter; 27 } 28 } 29 } 30 else 31 { 32 auto iter = std::find(_data.begin(), _data.end(), object); 33 if (iter != _data.end()) 34 { 35 _data.erase(iter); 36 object->release(); 37 } 38 } 39 } 40 41 /** brief Removes from the vector with an iterator.param position Iterator pointing to a single element to be removed from the Vector.return An iterator pointing to the new location of the element that followed the last element erased by the function call.This is the container end if the operation erased the last element in the sequence.指定位置移除对象,参数是迭代器,而返回值是下一个迭代器*/ 42 iterator erase(iterator position) 43 { 44 CCASSERT(position >= _data.begin() && position < _data.end(), "Invalid position!"); 45 (*position)->release(); 46 return _data.erase(position); 47 } 48 /** brief Removes from the Vector with a range of elements ( [first, last) ).param first The beginning of the range.param last The end of the range, the 'last' will not be removed, it's only for indicating the end of range.return An iterator pointing to the new location of the element that followed the last element erased by the function call.This is the container end if the operation erased the last element in the sequence.指定移除对象范围(first~last),参数是迭代器,而返回值是下一个迭代器*/ 49 iterator erase(iterator first, iterator last) 50 { 51 for (auto iter = first; iter != last; ++iter) 52 { 53 (*iter)->release(); 54 } 55 return _data.erase(first, last); 56 } 57 /** brief Removes from the Vector by index.param index The index of the element to be removed from the Vector.return An iterator pointing to the successor of Vector[index].移除一个值得索引的元素,参数是int类型,而返回值下一个迭代器*/ 58 iterator erase(ssize_t index) 59 { 60 CCASSERT(!_data.empty() && index >=0 && index < size(), "Invalid index!"); 61 auto it = std::next( begin(), index ); 62 (*it)->release(); 63 return _data.erase(it); 64 } 65 /** brief Removes all elements from the Vector (which are destroyed), leaving the container with a size of 0.note All the elements in the Vector will be released (reference count will be decreased).移除所有元素*/ 66 void clear() 67 { 68 for( auto it = std::begin(_data); it != std::end(_data); ++it ) { 69 (*it)->release(); 70 } 71 _data.clear(); 72 }
替换和交换元素的函数:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** Swap the values object1 and object2. 交换两个元素*/ 2 void swap(T object1, T object2) 3 { 4 ssize_t idx1 = getIndex(object1); 5 ssize_t idx2 = getIndex(object2); 6 7 CCASSERT(idx1>=0 && idx2>=0, "invalid object index"); 8 9 std::swap( _data[idx1], _data[idx2] ); 10 } 11 /** Swap two elements by indexes. 交换两个指定位置的元素*/ 12 void swap(ssize_t index1, ssize_t index2) 13 { 14 CCASSERT(index1 >=0 && index1 < size() && index2 >= 0 && index2 < size(), "Invalid indices"); 15 16 std::swap( _data[index1], _data[index2] ); 17 } 18 /** Replace value at index with given object. 用一个对象替代指定位置的元素*/ 19 void replace(ssize_t index, T object) 20 { 21 CCASSERT(index >= 0 && index < size(), "Invalid index!"); 22 CCASSERT(object != nullptr, "The object should not be nullptr"); 23 24 _data[index]->release(); 25 _data[index] = object; 26 object->retain(); 27 }
查找操作函数:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** brief Find the object in the Vector.param object The object to find.return Returns an iterator which refers to the element that its value is equals to object.Returns Vector::end() if not found.查找Vector容器中的对象,返回值迭代器*/ 2 const_iterator find(T object) const 3 { 4 return std::find(_data.begin(), _data.end(), object); 5 } 6 /** brief Find the object in the Vector.param object The object to find.return Returns an iterator which refers to the element that its value is equals to object.Returns Vector::end() if not found.查找Vector容器中的对象,返回值迭代器*/ 7 iterator find(T object) 8 { 9 return std::find(_data.begin(), _data.end(), object); 10 } 11 /** Returns the element at position 'index' in the Vector. 根据索引位置返回Vector容器中的元素*/ 12 T at(ssize_t index) const 13 { 14 CCASSERT( index >= 0 && index < size(), "index out of range in getObjectAtIndex()"); 15 return _data[index]; 16 } 17 /** Returns the first element in the Vector. 返回第一个元素*/ 18 T front() const 19 { 20 return _data.front(); 21 } 22 /** Returns the last element of the Vector. 返回最后一个元素*/ 23 T back() const 24 { 25 return _data.back(); 26 } 27 /** Returns a random element of the Vector. 返回随机的元素*/ 28 T getRandomObject() const 29 { 30 if (!_data.empty()) 31 { 32 ssize_t randIdx = rand() % _data.size(); 33 return *(_data.begin() + randIdx); 34 } 35 return nullptr; 36 } 37 /**Checks whether an object is in the container.param object The object to be checked.return True if the object is in the container, false if not.返回某个元素是否存在于容器中*/ 38 bool contains(T object) const 39 { 40 return( std::find(_data.begin(), _data.end(), object) != _data.end() ); 41 }
其他操作函数:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** Reverses the Vector. 反转Vector容器*/ 2 3 void reverse() 4 { 5 std::reverse( std::begin(_data), std::end(_data) ); 6 } 7 /** Requests the container to reduce its capacity to fit its size. 减少其以适应其容量大小*/ 8 void shrinkToFit() 9 { 10 _data.shrink_to_fit(); 11 } 12 13 /** Requests that the vector capacity be at least enough to contain n elements.param capacity Minimum capacity requested of the Vector.*/ 14 void reserve(ssize_t n) 15 { 16 _data.reserve(n); 17 } 18 /** brief Returns the size of the storage space currently allocated for the Vector, expressed in terms of elements.note This capacity is not necessarily equal to the Vector size.It can be equal or greater, with the extra space allowing to accommodate for growth without the need to reallocate on each insertion.return The size of the currently allocated storage capacity in the Vector, measured in terms of the number elements it can hold.返回容量的大小*/ 19 ssize_t capacity() const 20 { 21 return _data.capacity(); 22 } 23 /** brief Returns the number of elements in the Vector.note This is the number of actual objects held in the Vector, which is not necessarily equal to its storage capacity.return The number of elements in the Vector.返回元素的个数*/ 24 ssize_t size() const 25 { 26 return _data.size(); 27 } 28 /** @brief Returns whether the Vector is empty (i.e. whether its size is 0).note This function does not modify the container in any way. To clear the content of a vector, see Vector<T>::clear.判断容器是否为空*/ 29 bool empty() const 30 { 31 return _data.empty(); 32 } 33 /** Returns the maximum number of elements that the Vector can hold.容器的最大容量*/ 34 ssize_t max_size() const 35 { 36 return _data.max_size(); 37 } 38 /** Returns index of a certain object, return UINT_MAX if doesn't contain the object,通过给定的下标返回容器中对应的值 */ 39 ssize_t getIndex(T object) const 40 { 41 auto iter = std::find(_data.begin(), _data.end(), object); 42 if (iter != _data.end()) 43 return iter - _data.begin(); 44 45 return -1; 46 }
实例:
.h files #ifndef _VECTORTEST_SCENE_H_ #define _VECTORTEST_SCENE_H_ #include "cocos2d.h" class vectorTest : public cocos2d::Layer { private: public: static cocos2d::Scene* createScene(); virtual bool init(); void testVector(); CREATE_FUNC(vectorTest); }; #endif // _VECTORTEST_SCENE_H_ .cpp files #include "VectorTest.h" USING_NS_CC; Scene* vectorTest::createScene() { // 'scene' is an autorelease object auto scene = Scene::create(); // 'layer' is an autorelease object auto layer = vectorTest::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } bool vectorTest::init() { if (!Layer::init()) { return false; } testVector(); return true; } void vectorTest::testVector() { //首先创建一个精灵 auto sp1 = Sprite::create(); sp1->setTag(1); std::shared_ptr<Vector<Sprite*>> vec1 = std::make_shared<Vector<Sprite*>>(); vec1->pushBack(sp1); auto sp2 = Sprite::create(); sp2->setTag(2); //初始化一个大小为5的Vector容器 Vector<Sprite*> vec2(5); vec2.insert(0, sp2); //将vec1中的内容追加到Vec2的末尾 vec2.pushBack(*vec1); //遍历 for (auto sp : vec2) { log("sprite tag = %d", sp->getTag()); } //用另外的一个Vector来初始化一个Vector Vector<Sprite*> vec3(*vec1); //判断这两个Vec是否相等 if (vec1->equals(vec2)) { log("pVec1 is equal to pVec2"); } //判断是否为空 if (!vec2.empty()) { //capacity();函数是取得对应Vector对象的热量大小 if (vec2.capacity() == vec2.size()) { log("pVec2->capacity()==pVec2->size()"); } else { vec2.shrinkToFit(); log("pVec2->capacity()==%zd; pVec2->aize()==%zd", vec2.capacity(), vec2.size()); } vec2.swap(vec2.front(), vec2.back()); if (vec3.contains(sp1)) { log("The index of sp1 in pVec3 is %zd", vec3.getIndex(sp1)); } vec2.erase(vec2.find(sp1)); vec2.clear(); log("The size of pVac2 is %zd", vec2.size()); } }