本文来自http://blog.csdn.net/runaying ,引用必须注明出处!
温馨提醒:为了大家能更好学习,强烈推荐大家看看本人的这篇博客 Cocos2d-X权威指南笔记
这个类非常常用,可以存储任何对象,它可以模拟 C的指针,
///\cocos2d-x-3.0alpha0\cocos2dx\cocoa //这个类非常常用,可以存储任何对象,它可以模拟 C 的指针, #ifndef __CCARRAY_H__ #define __CCARRAY_H__ #define CC_USE_ARRAY_VECTOR 0 #if CC_USE_ARRAY_VECTOR #include <vector> #include <algorithm> #include "cocoa/CCObject.h" #include "ccMacros.h" #else #include "support/data_support/ccCArray.h" #endif #if CC_USE_ARRAY_VECTOR /** * 一个来自RCBase类的引用计数管理指针 * 可以作为 C 指针使用 * Original code: http://www.codeproject.com/Articles/64111/Building-a-Quick-and-Handy-Reference-Counting-Clas //源代码 * License: http://www.codeproject.com/info/cpol10.aspx //许可 */ template < class T > class RCPtr { public: //使用 C 指针的构造函数 //e.g. RCPtr< T > x = new T(); RCPtr(T* ptr = nullptr) : _ptr(ptr) { if(ptr != nullptr) {ptr->retain();} } //Copy 构造函数 RCPtr(const RCPtr &ptr) : _ptr(ptr._ptr) { // printf("Array: copy constructor: %p\n", this); if(_ptr != NULL) {_ptr->retain();} } //Move 构造函数 RCPtr(RCPtr &&ptr) : _ptr(ptr._ptr) { // printf("Array: Move Constructor: %p\n", this); ptr._ptr = nullptr; } ~RCPtr() { // printf("Array: Destructor: %p\n", this); if(_ptr != nullptr) {_ptr->release();} } //分配一个指针 //e.g. x = new T(); RCPtr &operator=(T* ptr) { // printf("Array: operator= T*: %p\n", this); //以下获取和释放操作必须执行 //按照这个顺序来处理 ptr == _ptr 的情况 //参阅 David Garlisch 的评论) if(ptr != nullptr) {ptr->retain();} if(_ptr != nullptr) {_ptr->release();} _ptr = ptr; return (*this); } //分配另一个 RCPtr RCPtr &operator=(const RCPtr &ptr) { // printf("Array: operator= const&: %p\n", this); return (*this) = ptr._ptr; } //Retrieve(检索)真实的指针 T* get() const { return _ptr; } //一些重载 operators 可以方便使用一个 RCPtr //作为一个传统的 C 指针. //如果没有这些 operators, 仍然可以使用但是透明度较低 //get() 方法来访问指针. T* operator->() const {return _ptr;} //x->member T &operator*() const {return *_ptr;} //*x, (*x).member explicit operator T*() const {return _ptr;} //T* y = x; explicit operator bool() const {return _ptr != nullptr;} //if(x) {/*x is not NULL*/} bool operator==(const RCPtr &ptr) {return _ptr == ptr._ptr;} bool operator==(const T *ptr) {return _ptr == ptr;} private: T *_ptr; //Actual pointer(真实的指针) }; #endif // CC_USE_ARRAY_VECTOR /** * @addtogroup data_structures * @{ */ /** @def CCARRAY_FOREACH 一个用来遍历 Array 的宏. 他比 "fast enumeration" 接口还要快. @since v0.99.4 */ /* In cocos2d-iphone 1.0.0, 这个 macro(宏) 已经更新;像这个: #define CCARRAY_FOREACH(__array__, __object__) \ if (__array__ && __array__->data->num > 0) \ for(id *__arr__ = __array__->data->arr, *end = __array__->data->arr + __array__->data->num-1; \ __arr__ <= end && ((__object__ = *__arr__) != nil || true); \ __arr__++) 我发现他不能在 C++ 里面工作.所以他看起来和 1.0.0-rc3 版本一样. ---By Bin */ #if CC_USE_ARRAY_VECTOR #define CCARRAY_FOREACH(__array__, __object__) \ if (__array__) \ for( auto __it__ = (__array__)->data.begin(); \ __it__ != (__array__)->data.end() && ((__object__) = __it__->get()) != nullptr; \ ++__it__) #define CCARRAY_FOREACH_REVERSE(__array__, __object__) \ if (__array__) \ for( auto __it__ = (__array__)->data.rbegin(); \ __it__ != (__array__)->data.rend() && ((__object__) = __it__->get()) != nullptr; \ ++__it__ ) #define CCARRAY_VERIFY_TYPE(__array__, __type__) void(0) #else // ! CC_USE_ARRAY_VECTOR -------------------------- #define CCARRAY_FOREACH(__array__, __object__) \ if ((__array__) && (__array__)->data->num > 0) \ for(Object** __arr__ = (__array__)->data->arr, **__end__ = (__array__)->data->arr + (__array__)->data->num-1; \ __arr__ <= __end__ && (((__object__) = *__arr__) != NULL/* || true*/); \ __arr__++) #define CCARRAY_FOREACH_REVERSE(__array__, __object__) \ if ((__array__) && (__array__)->data->num > 0) \ for(Object** __arr__ = (__array__)->data->arr + (__array__)->data->num-1, **__end__ = (__array__)->data->arr; \ __arr__ >= __end__ && (((__object__) = *__arr__) != NULL/* || true*/); \ __arr__--) #if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) #define CCARRAY_VERIFY_TYPE(__array__, __type__) \ do { \ if ((__array__) && (__array__)->data->num > 0) \ for(Object** __arr__ = (__array__)->data->arr, \ **__end__ = (__array__)->data->arr + (__array__)->data->num-1; __arr__ <= __end__; __arr__++) \ CCASSERT(dynamic_cast<__type__>(*__arr__), "element type is wrong!"); \ } while(false) #else #define CCARRAY_VERIFY_TYPE(__array__, __type__) void(0) #endif #endif // ! CC_USE_ARRAY_VECTOR // Common defines ----------------------------------------------------------------------------------------------- //常见的定义 #define arrayMakeObjectsPerformSelector(pArray, func, elementType) \ do { \ if(pArray && pArray->count() > 0) \ { \ Object* child; \ CCARRAY_FOREACH(pArray, child) \ { \ elementType pNode = static_cast<elementType>(child); \ if(pNode) \ { \ pNode->func(); \ } \ } \ } \ } \ while(false) #define arrayMakeObjectsPerformSelectorWithObject(pArray, func, object, elementType) \ do { \ if(pArray && pArray->count() > 0) \ { \ Object* child; \ CCARRAY_FOREACH(pArray, child) \ { \ elementType pNode = static_cast<elementType>(child); \ if(pNode) \ { \ pNode->func(object); \ } \ } \ } \ } \ while(false) NS_CC_BEGIN class CC_DLL Array : public Object, public Clonable { public: /** 创建一个空的 array.默认容量是10 * @js NA * @lua NA */ static Array* create(); /** 使用 objects 创建一个 array * @js NA */ static Array* create(Object* object, ...) CC_REQUIRES_NULL_TERMINATION; /** 使用 object 创建一个 array * @js NA */ static Array* createWithObject(Object* object); /** 使用指定容量创建一个 array * @js NA */ static Array* createWithCapacity(int capacity); /** 使用一个已经存在的 array 创建一个 array * @js NA */ static Array* createWithArray(Array* otherArray); /** @brief 从 file 生成一个 array 指针 @param pFileName *.plist 文件的文件名 @return 从 file 生成的 array 指针 * @js NA */ static Array* createWithContentsOfFile(const char* pFileName); /* @brief 他和 arrayWithContentsOfFile() 的含义相同,但它不能自动释放,所以 调用者应该手动调用调用release()。 * @js NA * @lua NA */ static Array* createWithContentsOfFileThreadSafe(const char* pFileName); /** * @js NA * @lua NA */ ~Array(); /** 初始化 array * @js NA * @lua NA */ bool init(); /** 使用 object 初始化一个 array * @js NA * @lua NA */ bool initWithObject(Object* object); /** 使用 objects 初始化一个 array * @js NA * @lua NA */ bool initWithObjects(Object* object, ...) CC_REQUIRES_NULL_TERMINATION; /** 使用指定容量初始化一个 array * @js NA * @lua NA */ bool initWithCapacity(int capacity); /** 使用一个已经存在的 array 创建一个 array * @js NA * @lua NA */ bool initWithArray(Array* otherArray); // 查询 Array /** Returns 这个 array 中元素的数量 * @js NA */ int count() const { #if CC_USE_ARRAY_VECTOR return data.size(); #else return data->num; #endif } /** Returns 这个 array 的容量 * @js NA */ int capacity() const { #if CC_USE_ARRAY_VECTOR return data.capacity(); #else return data->max; #endif } /** Returns 一个 certain(确定)对象的索引, return UINT_MAX 如果不包含这个对象返回 * @js NA * @lua NA */ int getIndexOfObject(Object* object) const; /** * @js NA */ CC_DEPRECATED_ATTRIBUTE int indexOfObject(Object* object) const { return getIndexOfObject(object); } /** Returns 返回 certain 索引对应的元素 * @js NA * @lua NA */ Object* getObjectAtIndex(int index) { CCASSERT(index>=0 && index < count(), "index out of range in getObjectAtIndex()"); #if CC_USE_ARRAY_VECTOR return data[index].get(); #else return data->arr[index]; #endif } CC_DEPRECATED_ATTRIBUTE Object* objectAtIndex(int index) { return getObjectAtIndex(index); } /** Returns 这个 array 的最后一个元素 * @js NA */ Object* getLastObject() { #if CC_USE_ARRAY_VECTOR return data.back().get(); #else if(data->num > 0) return data->arr[data->num-1]; return nullptr; #endif } /** * @js NA */ CC_DEPRECATED_ATTRIBUTE Object* lastObject() { return getLastObject(); } /** Returns 一个随机的 element * @js NA * @lua NA */ Object* getRandomObject(); /** * @js NA */ CC_DEPRECATED_ATTRIBUTE Object* randomObject() { return getRandomObject(); } /** Returns object 是否存在于 array 的标记. * @js NA */ bool containsObject(Object* object) const; /** @since 1.1 * @js NA */ bool isEqualToArray(Array* otherArray); // Adding Objects /** Add 一个确定的 object * @js NA */ void addObject(Object* object); /** * @js NA */ /** Add 添加一个已经存在 array 里面的所有的元素 * @js NA */ void addObjectsFromArray(Array* otherArray); /** Insert a certain object at a certain index * @js NA */ void insertObject(Object* object, int index); /** sets 添加一个已经存在 object 到指定索引 * @js NA * @lua NA */ void setObject(Object* object, int index); /** sets 一个已经存在 object 到指定索引, without retaining(不保存) . 所以请谨慎使用 * @js NA * @lua NA */ void fastSetObject(Object* object, int index) { #if CC_USE_ARRAY_VECTOR setObject(object, index); #else // no retain data->arr[index] = object; #endif } /** * @js NA * @lua NA */ void swap( int indexOne, int indexTwo ) { CCASSERT(indexOne >=0 && indexOne < count() && indexTwo >= 0 && indexTwo < count(), "Invalid indices"); #if CC_USE_ARRAY_VECTOR std::swap(data[indexOne], data[indexTwo]); #else std::swap(data->arr[indexOne], data->arr[indexTwo]); #endif } // Removing Objects /** Remove 最后一个 object * @js NA */ void removeLastObject(bool releaseObj = true); /** Remove 一个已经存在 object * @js NA */ void removeObject(Object* object, bool releaseObj = true); /** Remove 一个 certain 索引对应的对象 * @js NA */ void removeObjectAtIndex(int index, bool releaseObj = true); /** Remove all elements * @js NA */ void removeObjectsInArray(Array* otherArray); /** Remove all objects * @js NA */ void removeAllObjects(); /** 快速移除 一个已经存在的对象 * @js NA */ void fastRemoveObject(Object* object); /** 快速移除 一个 certain 索引所对应的对象 * @js NA */ void fastRemoveObjectAtIndex(int index); // Rearranging Content 重新排序内容 /** 交换两个元素 * @js NA */ void exchangeObject(Object* object1, Object* object2); /** 交换 3 个 certain 索引所对应的对象 * @js NA */ void exchangeObjectAtIndex(int index1, int index2); /** 替换指定索引对应的对象 * @js NA */ void replaceObjectAtIndex(int index, Object* object, bool releaseObject = true); /** Revers(反向) the array * @js NA */ void reverseObjects(); /* 收缩 array 这样的内存占用量,对应的 items 数 * @js NA */ void reduceMemoryFootprint(); /* override functions * @js NA */ virtual void acceptVisitor(DataVisitor &visitor); /** * @js NA * @lua NA */ virtual Array* clone() const; // ------------------------------------------ // Iterators // ------------------------------------------ #if CC_USE_ARRAY_VECTOR typedef std::vector<RCPtr<Object>>::iterator iterator; typedef std::vector<RCPtr<Object>>::const_iterator const_iterator; /** * @js NA * @lua NA */ iterator begin() { return data.begin(); } /** * @js NA * @lua NA */ iterator end() { return data.end(); } const_iterator cbegin() { return data.cbegin(); } /** * @js NA * @lua NA */ const_iterator cend() { return data.cend(); } std::vector<RCPtr<Object>> data; #else /** * @js NA * @lua NA */ Object** begin() { return &data->arr[0]; } /** * @js NA * @lua NA */ Object** end() { return &data->arr[data->num]; } ccArray* data; #endif //protected: /** * @js NA * @lua NA */ Array(); }; // end of data_structure group /// @} NS_CC_END #endif // __CCARRAY_H__