青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

安全的list

    好久沒有寫東西了,實在是忙,其實,準確說是懶。

    最近調試客戶端地圖管理的時候,老是出現對象在視野中進進出出后就會冒出個非法。而非法的原因大多跟list有關,就是在list遍歷顯示列表的時候,出現了增刪操作,而這個是list不能容忍的。由于系統比較大,要改的地方也多,而且好多異常情況也不是一下子就能改好的,當屏幕中的生物對象很多時,就容易出現。

想來想去,就想了一個能安全遍歷的list來解決問題。因為在實際上,當遍歷到一個list的節點時,會調用節點所含對象的update方法,該方法可能會觸發從地圖中刪除自己或者其他對象,這樣list就非法了。

下面是對標準list的簡單封裝,使之具有安全遍歷的特性,遍歷過程中可以增刪任何節點。原理很簡單,就是內部記住遍歷的當前節點,在刪除時做個比較。

//==========================================================================
/**
* @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
對標準list進行了簡單封裝,使之具有安全遍歷的功能(即:在遍歷過程中,支持增刪節點)

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

// 安全遍歷(允許在遍歷的過程中增刪任何數目的節點)
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);
    }

}
;

posted on 2008-11-15 01:41 PeakGao 閱讀(3423) 評論(11)  編輯 收藏 引用 所屬分類: C++技術

評論

# re: 安全的list 2008-11-16 09:40 winsty

這個不是線程安全的問題么……  回復  更多評論   

# ????? 2008-11-16 18:45 是什么

看不懂 是什么哦
電腦程序
  回復  更多評論   

# re: 安全的list[未登錄] 2008-11-17 10:30 PeakGao

@是什么
是這樣的,當list的操作很簡單時,遍歷list幾乎沒有什么問題,也可以在遍歷的時候刪除當前節點,如:
for (std::list<int>::iterator it=list.begin(); it!=list.end();)
{
if (條件為真)
it = list.erase(it); // 刪除當前節點
else
++it;
}

但是當這個list不是很簡單的遍歷時,而且刪除的時候也不是很顯式的在遍歷過程中時,就很容易出問題,如:

void MapManager::update(...)
{
// typedef std::list<Entity*> DisplayList;
for (DisplayList::iterator it=mDisplayList.begin(); it!=mDisplayList.end();)
{
(*it)->update(...);
}
}

但是(*it)->update(...);會調用到另一個模塊中去了,可能會這樣調用:
void Entity::update(...)
{
//...
MapManager->removeEntity(this);
}

而removeEntity會涉及到erase節點:
void MapManager::removeEntity(Entity* e)
{
mDisplayList.remove(e);
}

如果Entity的update方法中,發現自己的生命期已經結束的話,就會刪除自己,這樣MapManager::update里面就非法了,這是一個站在磚頭上拿掉磚頭的問題,必定非法。這個safelist就是為了支持在遍歷列表的過程中能安全的erase任何節點。

可能你們沒有碰到該類問題,或者使用list的時候沒有那么復雜,所以一時沒法去了解。  回復  更多評論   

# re: 安全的list 2008-11-17 14:33 不懂

std::list<int>::iterator itTmp;

for (std::list<int>::iterator it=list.begin(); it!=list.end();)
{
if (條件為真)
{
itTmp = it;
++itTmp;
it = list.erase(it); // 刪除當前節點
it = itTmp;
}
else
++it;
}
  回復  更多評論   

# re: 安全的list 2008-11-18 08:38 不懂

但是當這個list不是很簡單的遍歷時,而且刪除的時候也不是很顯式的在遍歷過程中時,就很容易出問題  回復  更多評論   

# re: 安全的list 2008-11-18 08:38 不懂

但是當這個list不是很簡單的遍歷時,而且刪除的時候也不是很顯式的在遍歷過程中時,就很容易出問題

如果真有這樣的問題,那就是框架有問題  回復  更多評論   

# re: 安全的list[未登錄] 2008-11-18 08:58 PeakGao

@不懂
理論上是這樣,框架徹底的好就沒有問題,但是在游戲更新時,經常有生命期結束的對象,這樣的對象需要從地圖上面移除,就涉及到從列表中erase,而生命期結束是根據update的調用進行檢測的。當然可以有另一個辦法,就是將檢測放到一個時鐘里面,而不是在list的遍歷過程中,但是這樣會需要好多多余的時鐘。再有一種辦法,就是對象要移除時,只設置一個需要移除的標志,在下一輪遍歷前才真正移除。發現越說越復雜了,總之,這個功能就是用于list遍歷很復雜時,也能安全的工作。你的這幾行,參考我上面的,就一句it=list.erase(it)迭代器不需要臨時保存的!!
for (std::list<int>::iterator it=list.begin(); it!=list.end();)
{
if (條件為真)
{
itTmp = it; // 多余
++itTmp; // 多余
it = list.erase(it); // 刪除當前節點
it = itTmp; // 多余
}
else
++it;
}   回復  更多評論   

# re: 安全的list 2008-11-18 09:29 Jeff Chen

LZ的情況,我也遇到過,困惑過。當我看完jabberd2的代碼后,覺得它的做法比較好。

方法如下:
程序每次先遍歷所有的Connection時,無效的Connection將自己移入一個CloseList中。
在遍歷所有的Connection后,程序接著清理CloseList里的Connection。

這樣做的好處,不會出現LZ這種list“重入”的問題,而且可以靈活處理不需要的對象。  回復  更多評論   

# re: 安全的list 2008-11-18 17:06 LOGOS

頂樓上
mark it & lazy delete

這樣做在在邏輯上更為完整,相對于作者直接刪除對象而言
  回復  更多評論   

# re: 安全的list[未登錄] 2008-11-20 13:35 PeakGao

@Jeff Chen
你這種其實就是我上面說的這個意思:“再有一種辦法,就是對象要移除時,只設置一個需要移除的標志,在下一輪遍歷前才真正移除。”,不過你的說法好像有問題哦,遍歷時根本不知道是無效的Connection哦,而且不能在遍歷的過程中將節點移入到另一個列表,這樣會掛的  回復  更多評論   

# re: 安全的list(更簡單的用法) 2009-01-08 08:46 canaan

http://zhgn.vicp.net/boke/200901071529.htm
List.erase(p)的用法  回復  更多評論   

<2008年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

導航

統計

常用鏈接

留言簿(9)

隨筆分類(67)

隨筆檔案(65)

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            日韩亚洲欧美一区二区三区| 欧美激情国产精品| 亚洲电影在线| 久久久人成影片一区二区三区| 亚洲欧美日韩综合国产aⅴ| 亚洲一区二区在线免费观看视频| 亚洲毛片一区| 亚洲一区在线观看免费观看电影高清| 一本色道88久久加勒比精品 | 欧美日韩成人| 欧美日韩午夜精品| 欧美高潮视频| 亚洲福利视频三区| 国产一区二区电影在线观看| 国产亚洲欧美一区在线观看| 国产在线精品二区| 国产一区在线免费观看| 亚洲人午夜精品免费| 亚洲国产另类久久精品| 亚洲影院免费| 欧美中文字幕不卡| 亚洲丁香婷深爱综合| 亚洲视屏在线播放| 久久免费视频一区| 免费视频最近日韩| 国产精品久久久久久久久久尿| 国产一区二区高清不卡| 亚洲免费播放| 久久精品国产欧美激情| 欧美激情一区二区三区在线| 亚洲日本激情| 性娇小13――14欧美| 欧美日本国产精品| 影音先锋在线一区| 午夜免费在线观看精品视频| 亚洲高清一区二| 性欧美video另类hd性玩具| 欧美日韩国产精品 | 日韩视频中文字幕| 欧美一区二区视频网站| 欧美日韩中文字幕精品| 永久免费精品影视网站| 亚洲欧美日韩精品在线| 免费人成网站在线观看欧美高清| 亚洲综合清纯丝袜自拍| 男人插女人欧美| 国产日韩欧美视频在线| 亚洲欧洲日本在线| 久久福利一区| 亚洲免费在线视频| 欧美三级电影大全| 亚洲免费成人av电影| 欧美88av| 久久综合久久综合久久| 国产亚洲欧美日韩日本| 欧美在线观看视频一区二区| 妖精成人www高清在线观看| 欧美精品播放| 亚洲狠狠丁香婷婷综合久久久| 久久理论片午夜琪琪电影网| 一本久道久久综合婷婷鲸鱼| 欧美日韩国产精品一卡| 亚洲天堂av综合网| 亚洲视频视频在线| 国产精品视频午夜| 欧美诱惑福利视频| 午夜日韩在线| 国产日韩在线视频| 久久久久久9| 激情欧美丁香| 麻豆精品国产91久久久久久| 影音先锋在线一区| 亚洲狠狠丁香婷婷综合久久久| 久久久久免费观看| 精品av久久707| 欧美国产一区视频在线观看| 欧美成人一区在线| 亚洲综合电影一区二区三区| 亚洲一区观看| 激情久久久久久| 亚洲日本中文字幕| 国产精品v欧美精品v日本精品动漫| 午夜免费在线观看精品视频| 久久精品国产99国产精品澳门| 亚洲免费高清| 先锋亚洲精品| 亚洲欧洲一区二区三区久久| 亚洲图片在线观看| 在线成人av.com| 亚洲美女毛片| 韩国三级电影久久久久久| 欧美激情性爽国产精品17p| 欧美日韩亚洲一区二区三区四区| 久久av红桃一区二区小说| 免费一级欧美片在线播放| 亚洲欧美日韩成人高清在线一区| 久久久久国色av免费观看性色| 在线亚洲一区| 久久精品国产亚洲高清剧情介绍| 亚洲精品一区二区三区樱花| 亚洲欧美文学| 在线综合亚洲| 久久视频精品在线| 亚洲欧美日韩人成在线播放| 久久综合中文| 久久精品夜夜夜夜久久| 欧美日韩免费看| 欧美成人午夜激情| 国产欧美日韩亚洲一区二区三区| 亚洲欧洲一二三| 激情综合中文娱乐网| 亚洲性xxxx| 亚洲最黄网站| 欧美va亚洲va国产综合| 久久国产精品久久久| 国产精品www| 91久久久亚洲精品| 亚洲国产成人porn| 欧美在线观看网站| 午夜精品国产精品大乳美女| 欧美日韩精品免费看 | 99re8这里有精品热视频免费| 亚洲欧美网站| 欧美一区二区高清在线观看| 欧美午夜一区| 国产精品99久久久久久久女警| 日韩一级在线观看| 免费的成人av| 欧美激情国产日韩精品一区18| 狠狠网亚洲精品| 欧美影院精品一区| 欧美一区2区三区4区公司二百| 亚洲一品av免费观看| 欧美日韩一区二区在线| 99视频精品全国免费| 一区二区三区视频在线观看| 欧美日韩三级视频| 亚洲理论电影网| 中文欧美字幕免费| 国产精品成人va在线观看| 亚洲天堂成人| 欧美在线免费观看亚洲| 国内精品免费午夜毛片| 久久精品欧洲| 欧美黄网免费在线观看| 亚洲国产精品久久久久| 欧美激情在线狂野欧美精品| 亚洲三级电影全部在线观看高清| 亚洲人午夜精品免费| 欧美日韩高清在线观看| 亚洲午夜视频在线| 久久久av水蜜桃| 在线日韩av片| 欧美激情综合亚洲一二区| 99精品视频免费| 欧美一区二区| 在线观看一区欧美| 欧美日韩系列| 欧美在线一级va免费观看| 欧美激情精品久久久久| 在线亚洲+欧美+日本专区| 国产欧美一区二区三区在线看蜜臀 | 亚洲看片一区| 国产精品久久国产三级国电话系列| 亚洲免费视频观看| 亚洲第一久久影院| 亚洲免费在线看| 在线激情影院一区| 欧美日韩一区二区在线观看| 久久成人免费日本黄色| 最近中文字幕mv在线一区二区三区四区| 亚洲欧美中文日韩在线| 亚洲国产成人porn| 国产精品丝袜91| 欧美日本不卡视频| 久久丁香综合五月国产三级网站| 欧美国产在线观看| 欧美一二三视频| 亚洲精品国产欧美| 国产三级欧美三级| 欧美片在线播放| 久久都是精品| 亚洲深夜福利| 欧美国产日韩亚洲一区| 欧美与欧洲交xxxx免费观看 | 欧美电影美腿模特1979在线看| 亚洲午夜久久久| 91久久精品一区二区别| 久久日韩粉嫩一区二区三区| 亚洲欧美一区二区在线观看| 99精品国产福利在线观看免费 | 欧美一级视频免费在线观看| 亚洲黄色在线视频| 国产在线精品一区二区夜色| 国产精品激情av在线播放| 欧美成人免费观看| 久久久久久网站| 欧美一区三区二区在线观看| 亚洲国产精品一区在线观看不卡| 免费高清在线一区|