好久沒有寫東西了,實(shí)在是忙,其實(shí),準(zhǔn)確說是懶。
最近調(diào)試客戶端地圖管理的時(shí)候,老是出現(xiàn)對(duì)象在視野中進(jìn)進(jìn)出出后就會(huì)冒出個(gè)非法。而非法的原因大多跟list有關(guān),就是在list遍歷顯示列表的時(shí)候,出現(xiàn)了增刪操作,而這個(gè)是list不能容忍的。由于系統(tǒng)比較大,要改的地方也多,而且好多異常情況也不是一下子就能改好的,當(dāng)屏幕中的生物對(duì)象很多時(shí),就容易出現(xiàn)。
想來想去,就想了一個(gè)能安全遍歷的list來解決問題。因?yàn)樵趯?shí)際上,當(dāng)遍歷到一個(gè)list的節(jié)點(diǎn)時(shí),會(huì)調(diào)用節(jié)點(diǎn)所含對(duì)象的update方法,該方法可能會(huì)觸發(fā)從地圖中刪除自己或者其他對(duì)象,這樣list就非法了。
下面是對(duì)標(biāo)準(zhǔn)list的簡單封裝,使之具有安全遍歷的特性,遍歷過程中可以增刪任何節(jié)點(diǎn)。原理很簡單,就是內(nèi)部記住遍歷的當(dāng)前節(jié)點(diǎn),在刪除時(shí)做個(gè)比較。
//==========================================================================

/**//**
* @file : safelist.h
* @author : PeakGao <peakgao163@163.com>
* created : 2008-11-13 20:21
* purpose : safe list
*/
//==========================================================================

#ifndef __safelist_h__
#define __safelist_h__

#include <list>


/**//** 安全list
對(duì)標(biāo)準(zhǔn)list進(jìn)行了簡單封裝,使之具有安全遍歷的功能(即:在遍歷過程中,支持增刪節(jié)點(diǎn))

// 普通遍歷
for (safelist<int>::const_iterator it = list.begin(); it!=list.end(); ++it)
{
Info("val = "<<*it<<endl);
}

// 安全遍歷(允許在遍歷的過程中增刪任何數(shù)目的節(jié)點(diǎn))
for (safelist<int>::iterator it=list.find_first(); it!=list.end(); it=list.find_next(it))
{
Info("val = "<<*it<<endl);
if (*it == 3)
{
list.erase(it);
}
}
*/
template<class _Ty, class _Ax = std::allocator<_Ty> >
class safelist : public std::list<_Ty, _Ax>


{
public:
typedef typename std::list<_Ty, _Ax> _Mybase;
typedef typename safelist<_Ty, _Ax> _Myt;
typedef typename _Mybase::_Alloc _Alloc;

private:

mutable _Nodeptr _Cur; /**//// the cursor for for_each

public:

safelist() : _Mybase(), _Cur(_Myhead)
{ }

explicit safelist(const _Alloc& _Al) : _Mybase(_Al), _Cur(_Myhead)
{ }

explicit safelist(size_type _Count) : _Mybase(_Count), _Cur(_Myhead)
{ }

safelist(size_type _Count, const _Ty& _Val) : _Mybase(_Count, _Val), _Cur(_Myhead)
{ }

safelist(size_type _Count, const _Ty& _Val, const _Alloc& _Al) : _Mybase(_Count, _Val, _Al), _Cur(_Myhead)
{ }

safelist(const _Mybase& _Right) : _Mybase(_Right), _Cur(_Myhead)
{ }

safelist(const _Myt& _Right) : _Mybase(_Right), _Cur(_Myhead)
{ }
template<class _Iter>

safelist(_Iter _First, _Iter _Last) : _Mybase(_First, _Last), _Cur(_Myhead)
{ }
template<class _Iter>

safelist(_Iter _First, _Iter _Last, const _Alloc& _Al) : _Mybase(_First, _Last, _Al), _Cur(_Myhead)
{ }

~safelist()

{
_Cur = 0;
}

void clear()

{
_Mybase::clear();
_Cur = _Myhead;
}

iterator erase(iterator _Where)

{
_Nodeptr cur = _Where._Mynode();
if (_Cur == cur)
_Cur = _Nextnode(cur);
return _Mybase::erase(_Where);
}

// 用于安全遍歷
public:

iterator find_first()
{ return iterator(_Cur = _Nextnode(_Myhead), this); }

const_iterator find_first() const
{ return const_iterator(_Cur = _Nextnode(_Myhead), this); }

iterator find_next(iterator cur)

{
if (cur._Mynode() == _Cur)
_Cur = _Nextnode(_Cur);
return iterator(_Cur, this);
}

const_iterator find_next(const_iterator cur) const

{
if (cur._Mynode() == _Cur)
_Cur = _Nextnode(_Cur);
return const_iterator(_Cur, this);
}
};
