Cocos2d::vector
Defined in the "CCVector.h" header file for "Cocos2dx_root/cocos/base".
template<class T>class CC_DLL Vector;
cocos2d::Vector<T>is a well-encapsulated container that dynamically grows sequential access. The cocos2d::Vector<T> elements in the sequence are accessed sequentially, and its lower-level implementation data structures are standard sequential containers in the standard Template Library std::vector . Before Cocos2d-x v3.0 Beta, another sequential access container was used cocos2d::CCArray , but it would be discarded. Designers will cocos2d::Vector<T> design cocos2d::CCArray alternatives, so it is recommended to use them first cocos2d::Vector<T> . cocos2d::Vector<T>the time complexity of some of the operations is as follows:
- Random Access, O (1)
- Inserts an element into the tail or removes the trailing element, O (1)
- Random insert or delete, O (n)
Template parameters
T -element type
- The type of t must be a pointer that inherits from
cocos2d::Object the type. Because the COCOS2D-X memory management model has been integrated into cocos2d::Vector<T> , the type parameter cannot be other types including the base type.
Memory management
cocos2d::Vector<T>The class contains only one member of the data:
std::vector<T> _data;
_dataMemory management is handled automatically by the compiler, and if you declare a cocos2d::Vector<T> type, you do not have to bother to free up memory. Note : Using modern C + +, local storage objects are better than heap storage objects. So please do not use the new operation to request cocos2d::Vector<T> the heap object, using the Stack object. If you really want to allocate cocos2d::Vector<T> the heap dynamically, overwrite the original pointer with a smart pointer. warning : cocos2d::Vector<T> not cocos2d::Object a subclass, so do not use Retain/release and reference count memory management as with other cocos2d classes.
Basic usage
The
authors use std::vector<t> 's basic operation plus Cocos2d-x's memory management rules to override the original normal operation of the template. So the pushback () operation will retain the passed arguments, and Popback () will release the last element in the container. When you use these actions, you need to pay particular attention to these managed objects, which are often pitfalls for beginners. Warning: cocos2d::vector<t> does not overload the [] operation, so the subscript [i] cannot be used directly to obtain the I-bit element. Cocos2d::vector<t> provides different types of iterators, so we can benefit from the standard libraries of C + +, and we can use a number of standard generic algorithms and For_each loops. In addition to the operations of the Std::vector container, developers have added many standard algorithms such as Std::find , std::reverse and Std::swap , these algorithms can simplify a lot of common operations. To learn more about the API use cases, you can refer to the Cocos2d-x 3.0beta source code and compression package included in the example. Here are some simple examples:
Create vector<sprite*> with default size and add a Sprite into Itauto sp0 = Sprite::create (); Sp0->settag (0);//h Ere we use shared_ptr just as a demo. In your code, use stack object insteadstd::shared_ptr<vector<sprite*>> vec0 = Std::make_shared<vec Tor<sprite*>> (); Default Constructorvec0->pushback (SP0);//create a vector<object*> with a capacity of 5 and add a sprite into it Auto SP1 = sprite::create (); Sp1->settag (1)//initialize a vector with a capacityvector<sprite*> vec1 (5);// Insert a certain object at a certain Indexvec1.insert (0, SP1);//we can also add a whole vectorvec1.pushback (*VEC0); for (AUT o sp:vec1) {log ("Sprite tag =%d", Sp->gettag ());} Vector<sprite*> vec2 (*VEC0); if (Vec0->equals (VEC2)) {//returns True if the-the-vectors is equal log ("PVec0 I s equal to PVec2 ");} if (!vec1.empty ()) {//whether The vector is empty//get the capacity and a size of the vector, noted that the capacity is not NECessarily equal to the vector size. if (vec1.capacity () = = Vec1.size ()) {log ("pvec1->capacity () ==pvec1->size ()"); }else{Vec1.shrinktofit (); Shrinks the vector so the memory footprint corresponds with the number of items log ("pvec1->capacity () ==%zd; Pvec1->size () ==%zd ", vec1.capacity (), vec1.size ()); }//pvec1->swap (0, 1); Swap elements in vectors by their index Vec1.swap (Vec1.front (), Vec1.back ()); Swap of elements in vectors by their value if (Vec2.contains (SP0)) {//returns A Boolean value that indicates whethe R object is present in vector log ("The index of SP0 in PVEC2 is%zd", Vec2.getindex (SP0)); }//remove the element from the Vector vec1.erase (Vec1.find (SP0)); Pvec1->erase (1); Pvec1->eraseobject (sp0,true); Pvec1->popback (); Vec1.clear (); Remove all elements Logs ("The size of PVEC1 is%zd", vec1.size ());}
Output:
Cocos2d: sprite tag = 1Cocos2d: sprite tag = 0Cocos2d: pVec0 is equal to pVec2Cocos2d: pVec1->capacity()==2; pVec1->size()==2Cocos2d: The index of sp0 in pVec2 is 0Cocos2d: The size of pVec1 is 0
Best practices
- Consider stack-based
cocos2d::Vector<T> precedence for heap-based
- When
cocos2d::Vector<T> passed as a parameter, it is declared as a constant reference:const cocos2d::Vector<T>&
- The return value is the
cocos2d::Vector<T> direct return value, in which case the compiler optimizes the move operation.
- Do not use any data type that does not have an inherited Cocos2d::object type
cocos2d::Vector<T> .
Cocos2d::map<k,v>
Defined in the "CCMap.h" header file for "Cocos2dx_root/cocos/base".
template <class K, class V>class CC_DLL Map;
cocos2d::Map<K,V>is an std::unordered_map associative container that is used as the underlying structure. std::unordered_mapIt is an associative container that stores key-value pairs that can quickly retrieve corresponding values through their keys. With Unordered_map, the key is usually unique, while the value corresponds to the key.
Inside Unordered_map, elements are unordered, they are accessed according to the hash value of the key, and the time complexity of the access is constant, super fast.
Before Cocos2d-x V3.0beta, a different sequential container was used cocos2d::CCDictionary , but it would soon be discarded.
Designers have been careful to devise cocos2d::Map<K,V> alternatives cocos2d::CCDictionary , so they should try to use them rather cocos2d::Map thancocos2d::CCDictionary
Template parameters
cocos2d::Map<K,V>class contains only one data member:
typedef std::unordered_map<K, V> RefMap;RefMap _data;
_dataMemory management is handled by the compiler, and when you declare an object in the stack cocos2d::Map<K,V> , you do not have to worry about releasing the memory it occupies. But if you are using an new operation to dynamically allocate memory, you cocos2d::Map<K,V> have to use it delete to free up memory, and the operation is the new[] same.
Note : Using modern C + +, local storage objects are better than heap storage objects. Therefore, do not use new the action to allocate cocos2d::Map<K,V> the heap object, using the Stack object.
If you really want to allocate cocos2d::Map<K,V> the heap dynamically, overwrite the original pointer with a smart pointer.
warning : cocos2d::Map<K,V> not cocos2d::Object a subclass, so do not use Retain/release and reference count memory management as with other cocos2d classes.
Basic Use Cases
warning : Do cocos2d::Map<K,V> not overload the [] operation, do not use subscript [i] to fetch cocos2d::Map<K,V> elements from the object.
- To learn more about the use cases, you have to refer to the examples provided in the source code and the zip file. Here are some examples of simple operations:
Create Map<k, v> with default size and add a sprite into Itauto sp0 = Sprite::create (); Sp0->settag (0); Map<std::string, sprite*> map0;std::string mapKey0 = "Map_key_0"; Map0.insert (MapKey0, sp0); log ("The size of MAP is %zd. ", Map0.size ()); Create a map<k, v> with capacity equals 5map<std::string, sprite*> map1 (map0); std::string mapKey1 = "Map_key _1 "; if (!map1.empty ()) {Auto Sptemp = (sprite*) map1.at (MAPKEY0); Log ("Sprite tag =%d", Sptemp->gettag ()); Auto SP1 = sprite::create (); Sp1->settag (1); Map1.insert (mapKey1, SP1); Get all keys,stored in std::vector, that matches the object std::vector<std::string> Mapkeyvec; Mapkeyvec = Map1.keys (); for (auto Key:mapkeyvec) {Auto Sptag = map1.at (key)->gettag (); Log ("The Sprite tag =%d, MAP key =%s", sptag,key.c_str ()); Log ("Element with key%s was located in bucket%zd", key.c_str (), Map1.bucket (key)); } log ("%zd buckets in the Map containeR ", Map1.bucketcount ()); Log ("%zd element in bucket 1", map1.bucketsize (1)); Get a Random object if the map isn ' t empty, otherwise it returns NULLPTR log ("the random object tag =%d", Map1.getran Domobject ()->gettag ()); Find (const k& key) can is used to search the container for a element with ' key '//erase (const_iterator position) Remove an element with a iterator log ("Before remove sp0, size of map is%zd.", Map1.size ()); Map1.erase (Map1.find (mapKey0)); Log ("After remove sp0, size of map is%zd.", Map1.size ());} Create a map<k, v> with capacity equals 5map<std::string, sprite*> map2 (5); Map2.reserve (10); Set capacity of the map
The result is:
cocos2d: The size of map is 1.cocos2d: sprite tag = 0cocos2d: The Sprite tag = 1, MAP key = MAP_KEY_1cocos2d: Element with key MAP_KEY_1 is located in bucket 1cocos2d: The Sprite tag = 0, MAP key = MAP_KEY_0cocos2d: Element with key MAP_KEY_0 is located in bucket 0cocos2d: 2 buckets in the Map containercocos2d: 1 element in bucket 1cocos2d: The random object tag = 0cocos2d: Before remove sp0, size of map is 2.cocos2d: After remove sp0, size of map is 1.
Best Use
cocos2d::Map<K,V>()when passed as a parameter, declare it as a constant referenceconst cocos2d::Map<K,V>()&
- The V type must be a
cocos2d::Object child class pointer and cannot include the base type with other types.
Cocos2d::value
defined in the header file "CCValue.h" of "cocos2dx_root/cocos/base"
class Value;
cocos2d::ValueThere are many basic types (,,,, int float double bool unsigned char,char* and std::string ) as well std::vector<Value> , and the std::unordered_map<std::string,Value> std::unordered_map<int,Value> wrapper types for these classes.
You can put the basic classes mentioned above into cocos2d::Value objects to convert them into corresponding types, and vice versa.
cocos2d::ValueThe underlying uses a uniform variable to hold any base type value, which will save memory more. In the Cocos2d-x v3.0beta previous use, CCBool CCFloat CCDouble and CCInteger such basic type wrapper classes, but they will be discarded.
Note : When dealing with basic types and containers, use cocos2d::Vector<T> , cocos2d::Map<K,V> and cocos2d::Value .
Memory management
cocos2d::ValueMemory is freed by its destructor, so use cocos2d::Value recommended best practices whenever possible.
cocos2d::ValueContains the following data members:
union{ unsigned char byteVal; int intVal; float floatVal; double doubleVal; bool boolVal;}_baseData;std::string _strData;ValueVector* _vectorData;ValueMap* _mapData;ValueMapIntKey* _intKeyMapData;Type _type;
The code snippet, _baseData _strData and the _type compiler and their destructors are responsible for freeing the memory, while cocos2d::Value the destructor is responsible for releasing the pointer members ( _vectorData , _mapData and intKeyMapData ).
Note : cocos2d::Value You cannot use Retain/release and RefCount memory management like other cocos2d types
Basic usage
ocos2d::ValueThe usage is very simple and straightforward. Here is an example of the use:
Value Val; Call the default Constructorif (Val.isnull ()) {log ("Val is null");} else{std::string str =val.getdescription (); Log ("The description of val0:%s", Str.c_str ());} ----------------------------------------------------Value Val1 (65); Initialize with a integer//value val1 (3.4f); Initialize with a float Value//value val1 (3.5); Initialize with a double Valuelog ("The description of the the integer value:%s", Val1.getdescription (). C_STR ()); Log (" Val1.asbyte () =%c ", Val1.asbyte ());//----------------------------------------------------std::string STRV =" string "; Value Val2 (STRV); Initialize with Stringlog ("The description of the string value:%s", Val2.getdescription (). C_STR ());//--------------- -------------------------------------Auto sp0 = Sprite::create (); vector<object*>* vecv = new vector<object*> (); Vecv->pushback (SP0); Value Val3 (VECV); Initialize with Vectorlog ("The description of the Vector value:%s", Val3.getdescription (). C_STR ());d ElEte vecv;//----------------------------------------------------map<std::string, object*>* MAPV = new map< std::string, object*> (); Mapv->insert (STRV,SP0); Value Val4 (MAPV); Initialize with Maplog ("The description of the Map value:%s", Val4.getdescription (). C_STR ());d elete mapv;//---------- ------------------------------------------Value val6 (&VAL4); Initialize with Maplog ("The description of the Value-type value:%s", Val6.getdescription (). C_STR ());//-------------- --------------------------------------val2 = val1; Assigning between 2 Value-typelog ("operator-> The description of val2:%s", Val2.getdescription (). C_STR ()); val2 = 4; assigning Directlylog ("operator-> The description of val4:%s", Val2.getdescription (). C_STR ());
The result is:
cocos2d: val is nullcocos2d: The description of the integer value:65cocos2d: val1.asByte() = Acocos2d: The description of the string value:stringcocos2d: The description of the Vector value:truecocos2d: The description of the Map value:truecocos2d: The description of the Value-type value:truecocos2d: operator-> The description of val2:65cocos2d: operator-> The description of val4:4
Best Use
- Consider using Cocos2d::value and new template containers (Cocos2d::vector and cocos2d::map<k,v>) better than using Cocos2d::ccbool, cocos2d::ccfloat,cocos2d :: Ccdouble,cocos2d::ccstring,cocos2d::ccinteger and old objective-c-style containers (Cocos2d::ccarray and cocos2d::ccdictionary).
- When you want to use a base type of aggregation, wrap the base types into Cocos2d::value, and then use them in conjunction with the template container cocos2d::vector and cocos2d::map<k,v>.
(18) Data structure