深入理解Cocos2d-x 3.x:内置数据结构(2)Map

前端之家收集整理的这篇文章主要介绍了深入理解Cocos2d-x 3.x:内置数据结构(2)Map前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

其实最没意思的数据结构就是Map和Vector这两个了,完完全全就是std::map和std::vector上面再加了一层引用计数。当然,这也有好处,就是支持std算法以及支持Cocos2d-x的内存管理机制。

看源码可以知道(下均只对Map进行分析,Vector同理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template < class K, V>
Map
{
public :
@H_404_71@ //------------------------------------------
//Iterators
//------------------------------------------
#ifUSE_STD_UNORDERED_MAP
@H_404_71@ typedef std::unordered_map<K,V>RefMap;
#else
@H_404_71@std::map<K,V>RefMap;
#endif
protected :
@H_404_71@ RefMap_data;
};

内部的数据结构就是一个std::unordered_map,但是Cocos2d-x对其做了一个限制,V必须是由Ref派生出来的数据类型,这样才能支持内存管理机制,下面是构造函数(有多个构造函数,只列举了一个)

7
/**Defaultconstructor*/
Map<K,V>()
:_data()
{
@H_404_71@static_assert(std::is_convertible<V,Ref*>::value, "InvalidTypeforcocos2d::Map<K,V>!" );
@H_404_71@CCLOGINFO( "InthedefaultconstructorofMap!" );
}

static_assert是表示在编译时检查,std::is_convertible是检测V与Ref*是否是继承关系,如果是,value为true,检测通过。如果不是,会在编译期就告诉我们,这个地方编译不过。

接下来就是插入函数

12
/**@briefInsertsnewelementsinthemap.
*@noteIfthecontainerhasalreadycontainedthekey,thisfunctionwillerasetheoldpair(key,object)andinsertthenewpair.
*@paramkeyThekeytobeinserted.
*@paramobjectTheobjecttobeinserted.
*/
void insert( const K&key,Vobject)
{
@H_404_71@CCASSERT(object!=nullptr,monospace!important; font-size:1em!important; min-height:inherit!important; color:blue!important">"Objectisnullptr!" );
@H_404_71@erase(key);
@H_404_71@_data.insert(std::make_pair(key,object));
@H_404_71@object->retain();
值得注意的是,这里先有一个删除操作,再进行插入,这样为了保证所有的key都是唯一值,但是这样会多造成一次遍历,因为unordered_map的插入是无序的,所以unordered_map的insert操作的复杂度是O(1),但是erase的删除必须要find key,所以会有O(N)的复杂度,所以效率会比直接使用unordered_map低。

然后是retain,保持对V类型的object的强引用

接下来是删除函数

15
16
17
/**@briefRemovesanelementwithaniteratorfromtheMap<K,V>container.
*@paramkKeyoftheelementtobeerased.
*Membertype'K'isthetypeofthekeysfortheelementsinthecontainer,
*definedinMap<K,V>asanaliasofitsfirsttemplateparameter(Key).
*/
size_t erase( K&k)
autoiter=_data.find(k);
if (iter!=_data.end())
@H_404_71@{
@H_404_71@iter->second->release();
@H_404_71@_data.erase(iter);
return 1;
@H_404_71@}
@H_404_71@
@H_404_71@0;
首先find到K,然后先执行release,再删除,返回1表示删除成功,0表示删除失败。

还有一些有意思的函数,如下这个

11
VgetRandomObject() const
{
@H_404_71@(!_data.empty())
@H_404_71@ssize_trandIdx= rand ()%_data.size();
@H_404_71@const_iteratorrandIter=_data.begin();
@H_404_71@std::advance(randIter,randIdx);
@H_404_71@randIter->second;
@H_404_71@}
@H_404_71@nullptr;
函数的作用是返回一个随机对象,首先判断非空,然后获取一个(0-data.size)的随机数,使用std::advance给begin增加一个随机数的长度,返回这个长度的迭代器。


感谢本文笔者NxShow的分享,Cocos引擎中文官网欢迎更多的开发者分享开发经验。来稿请发送至:support@cocos.org

来源网址:http://www.jb51.cc/article/p-scojlsah-bbn.html

原文链接:https://www.f2er.com/cocos2dx/341816.html

猜你在找的Cocos2d-x相关文章