In fact, the most boring data structure is the map and vector two, completely is std::map and std::vector above added a layer of reference count. Of course, this also has the benefit of supporting the STD algorithm and the memory management mechanism that supports cocos2d-x.
Look at the source code can be known (below are only the map analysis, vector the same)
Template <class K, class V>class Map{public: //------------------------------------------ //iterators //------------------------------------------#if use_std_unordered_map typedef std::unordered_map<k, V > Refmap, #else typedef std::map<k, v> refmap; #endifprotected: Refmap _data;};
The internal data structure is a std::unordered_map, but Cocos2d-x has a restriction on it, v must be a data type derived from ref, in order to support the memory management mechanism, the following is a constructor (with multiple constructors, only one listed)
/** Default Constructor */ Map<k, v> () : _data () { static_assert (std::is_convertible<v, Ref *>::value, "Invalid Type for Cocos2d::map<k, v>!"); Ccloginfo ("in the default constructor of map!"); }
Static_assert is a check at compile time, std::is_convertible is to detect if V is an inheritance relationship with ref*, and if yes, value is true to detect pass. If not, it will tell us at compile time, this place compiles however.
The next step is inserting the function
/** @brief inserts new elements in the map. * @note If The container have already contained the key, this function would erase the old pair (key, object) and ins ERT the new pair. * @param key The key to be inserted. * @param object The object to be inserted. * /void Insert (const k& key, V object) { Ccassert (Object! = nullptr, "object is nullptr!"); Erase (key); _data.insert (Std::make_pair (Key, object)); Object->retain (); }
It is important to note that there is a delete operation, then insert, so as to ensure that all keys are unique values, but this will cause a more traversal, because the unordered_map insert is unordered, so unordered_ The complexity of the insert operation of Map is O (1), but the erase must be found key, so there will be an O (N) complexity, so the efficiency will be lower than the direct use of unordered_map.
Then there is the retain, which maintains a strong reference to the Type V object.
The next step is to delete the function
/** @brief removes an element with a iterator from the map<k, v> container. * @param k Key of the element to be erased. * Member type ' K ' is the type of the keys for the elements in the container, * defined in map<k, v> as a n alias of its first template parameter (Key). * /size_t Erase (const k& K) { Auto iter = _data.find (k); if (iter! = _data.end ()) { iter->second->release (); _data.erase (ITER); return 1; } return 0; }
First find to K, and then first execute release, then delete, return 1 to delete the success, 0 means that the deletion failed.
There are some interesting functions, like this one.
V getrandomobject () const { if (!_data.empty ()) { ssize_t randidx = rand ()% _data.size (); Const_iterator Randiter = _data.begin (); Std::advance (Randiter, randidx); Return randiter->second; } return nullptr; }
function is to return a random object, first judge non-null, then get a random number (0-data.size), using std::advance to begin to increase the length of a random number, return this length of the iterator.
"Learn more about Cocos2d-x 3.x" built-in data structure (1)--map