好久没有写东西了,实在是忙,其实,准确说是懒。
    最近调试客户端地图管理的时候,老是出现对象在视野中进进出出后就会冒出个非法。而非法的原因大多跟list有关,就是在list遍历显示列表的时候,出现了增删操作,而这个是list不能容忍的。由于系统比较大,要改的地方也多,而且好多异常情况也不是一下子就能改好的,当屏幕中的生物对象很多时,就容易出现。
想来想去,就想了一个能安全遍历的list来解决问题。因为在实际上,当遍历到一个list的节点时,会调用节点所含对象的update方法,该方法可能会触发从地图中删除自己或者其他对象,这样list就非法了。
下面是对标准list的简单封装,使之具有安全遍历的特性,遍历过程中可以增删任何节点。原理很简单,就是内部记住遍历的当前节点,在删除时做个比较。
 //==========================================================================
//==========================================================================

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

 #ifndef __safelist_h__
#ifndef __safelist_h__
 #define __safelist_h__
#define __safelist_h__

 #include <list>
#include <list>


 /**//** 安全list
/**//** 安全list
 对标准list进行了简单封装,使之具有安全遍历的功能(即:在遍历过程中,支持增删节点)
对标准list进行了简单封装,使之具有安全遍历的功能(即:在遍历过程中,支持增删节点)

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

 // 安全遍历(允许在遍历的过程中增删任何数目的节点)
// 安全遍历(允许在遍历的过程中增删任何数目的节点)
 for (safelist<int>::iterator it=list.find_first(); it!=list.end(); it=list.find_next(it))
for (safelist<int>::iterator it=list.find_first(); it!=list.end(); it=list.find_next(it))
 {
{
 Info("val = "<<*it<<endl);
    Info("val = "<<*it<<endl);
 if (*it == 3)
    if (*it == 3)
 {
    {
 list.erase(it);
        list.erase(it);
 }
    }
 }
}
 */
*/
 template<class _Ty, class _Ax = std::allocator<_Ty> >
template<class _Ty, class _Ax = std::allocator<_Ty> >
 class safelist : public std::list<_Ty, _Ax>
class safelist : public std::list<_Ty, _Ax>


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

 private:
private:

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

 public:
public:

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

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

 explicit safelist(size_type _Count) : _Mybase(_Count), _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) : _Mybase(_Count, _Val), _Cur(_Myhead)  { }
{ }

 safelist(size_type _Count, const _Ty& _Val, const _Alloc& _Al) : _Mybase(_Count, _Val, _Al), _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 _Mybase& _Right) : _Mybase(_Right), _Cur(_Myhead)  { }
{ }

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

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

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

 ~safelist()
    ~safelist()

 
     {
{
 _Cur = 0;
        _Cur = 0;
 }
    }

 void clear()
    void clear()

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

 iterator erase(iterator _Where)
    iterator erase(iterator _Where)

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

 // 用于安全遍历
    // 用于安全遍历
 public:
public:

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

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

 iterator find_next(iterator cur)
    iterator find_next(iterator cur)

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

 const_iterator find_next(const_iterator cur) const
    const_iterator find_next(const_iterator cur) const

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