深入理解Cocos2d-x 3.x:内置数据结构(2)Map
来源:互联网 发布:牛顿环实验数据及 编辑:程序博客网 时间:2024/06/06 09:05
其实最没意思的数据结构就是Map和Vector这两个了,完完全全就是std::map和std::vector上面再加了一层引用计数。当然,这也有好处,就是支持std算法以及支持Cocos2d-x的内存管理机制。
看源码可以知道(下均只对Map进行分析,Vector同理)
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;
#endif
protected
:
RefMap _data;
};
内部的数据结构就是一个std::unordered_map,但是Cocos2d-x对其做了一个限制,V必须是由Ref派生出来的数据类型,这样才能支持内存管理机制,下面是构造函数(有多个构造函数,只列举了一个)
/** 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是表示在编译时检查,std::is_convertible是检测V与Ref*是否是继承关系,如果是,value为true,检测通过。如果不是,会在编译期就告诉我们,这个地方编译不过。
接下来就是插入函数
/** @brief Inserts new elements in the map.
* @note If the container has already contained the key, this function will erase the old pair(key, object) and insert 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();
}
值得注意的是,这里先有一个删除操作,再进行插入,这样为了保证所有的key都是唯一值,但是这样会多造成一次遍历,因为unordered_map的插入是无序的,所以unordered_map的insert操作的复杂度是O(1),但是erase的删除必须要find key,所以会有O(N)的复杂度,所以效率会比直接使用unordered_map低。
然后是retain,保持对V类型的object的强引用
接下来是删除函数
/** @brief Removes an element with an 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 an 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;
}
首先find到K,然后先执行release,再删除,返回1表示删除成功,0表示删除失败。
还有一些有意思的函数,如下这个
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;
}
函数的作用是返回一个随机对象,首先判断非空,然后获取一个(0-data.size)的随机数,使用std::advance给begin增加一个随机数的长度,返回这个长度的迭代器。
感谢本文笔者NxShow的分享,Cocos引擎中文官网欢迎更多的开发者分享开发经验。来稿请发送至:support@cocos.org。
来源网址:http://blog.csdn.net/nxshow/article/details/44750235
- 深入理解Cocos2d-x 3.x:内置数据结构(2)Map
- 【深入了解cocos2d-x 3.x】内置数据结构(2)——Map
- 【深入了解cocos2d-x 3.x】内置数据结构(1)——智能指针
- 深入理解 cocos2d-x 坐标系
- cocos2d-x 3.0 数据结构(2/3) cocos2d::Map
- 深入理解 Cocos2d-x 内存管理
- 深入理解 Cocos2d-x 内存管理
- 深入理解 Cocos2d-x 内存管理
- 深入理解 Cocos2d-x 内存管理
- 深入理解 Cocos2d-x 内存管理
- 深入理解 Cocos2d-x 内存管理
- 深入理解 Cocos2d-x 内存管理 转
- 深入理解 Cocos2d-x 内存管理
- 深入理解 Cocos2d-x 内存管理
- 深入理解 Cocos2d-x 内存管理
- cocos2d-x的LayoutParameter布局深入理解
- Cocos2d-x 3.0数据结构——cocos2d::Map
- 【深入了解cocos2d-x 3.x】定时器(scheduler)的使用和原理探究(2)
- 初入android驱动之字符设备(三)
- POJ-1562Oil Deposits
- Codeforces Round #315 (Div. 2)
- VS2015/MFC编辑框基本操作
- 实战iOS 9:开发者必须掌握的三种搜索API
- 深入理解Cocos2d-x 3.x:内置数据结构(2)Map
- ScrollView包裹ListView的两种处理方法
- fork() 问题
- QT信号和槽使用自定义的类或结构体
- Error: L6218E: Undefined symbol main (referred from entry9a.o).
- Markdown实现首行缩进
- sqlite3 — 轻量级嵌入式平台数据库开源软件
- Java中Object转化为int类型
- 类模板