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

安全的list

    好久沒(méi)有寫(xiě)東西了,實(shí)在是忙,其實(shí),準(zhǔn)確說(shuō)是懶。

    最近調(diào)試客戶(hù)端地圖管理的時(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)。

想來(lái)想去,就想了一個(gè)能安全遍歷的list來(lái)解決問(wèn)題。因?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ǎn)單封裝,使之具有安全遍歷的特性,遍歷過(guò)程中可以增刪任何節(jié)點(diǎn)。原理很簡(jiǎ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ǎn)單封裝,使之具有安全遍歷的功能(即:在遍歷過(guò)程中,支持增刪節(jié)點(diǎn))

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

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

}
;

posted on 2008-11-15 01:41 PeakGao 閱讀(3414) 評(píng)論(11)  編輯 收藏 引用 所屬分類(lèi): C++技術(shù)

評(píng)論

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

這個(gè)不是線程安全的問(wèn)題么……  回復(fù)  更多評(píng)論   

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

看不懂 是什么哦
電腦程序
  回復(fù)  更多評(píng)論   

# re: 安全的list[未登錄](méi) 2008-11-17 10:30 PeakGao

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

但是當(dāng)這個(gè)list不是很簡(jiǎn)單的遍歷時(shí),而且刪除的時(shí)候也不是很顯式的在遍歷過(guò)程中時(shí),就很容易出問(wèn)題,如:

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

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

而removeEntity會(huì)涉及到erase節(jié)點(diǎn):
void MapManager::removeEntity(Entity* e)
{
mDisplayList.remove(e);
}

如果Entity的update方法中,發(fā)現(xiàn)自己的生命期已經(jīng)結(jié)束的話(huà),就會(huì)刪除自己,這樣MapManager::update里面就非法了,這是一個(gè)站在磚頭上拿掉磚頭的問(wèn)題,必定非法。這個(gè)safelist就是為了支持在遍歷列表的過(guò)程中能安全的erase任何節(jié)點(diǎn)。

可能你們沒(méi)有碰到該類(lèi)問(wèn)題,或者使用list的時(shí)候沒(méi)有那么復(fù)雜,所以一時(shí)沒(méi)法去了解。  回復(fù)  更多評(píng)論   

# 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); // 刪除當(dāng)前節(jié)點(diǎn)
it = itTmp;
}
else
++it;
}
  回復(fù)  更多評(píng)論   

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

但是當(dāng)這個(gè)list不是很簡(jiǎn)單的遍歷時(shí),而且刪除的時(shí)候也不是很顯式的在遍歷過(guò)程中時(shí),就很容易出問(wèn)題  回復(fù)  更多評(píng)論   

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

但是當(dāng)這個(gè)list不是很簡(jiǎn)單的遍歷時(shí),而且刪除的時(shí)候也不是很顯式的在遍歷過(guò)程中時(shí),就很容易出問(wèn)題

如果真有這樣的問(wèn)題,那就是框架有問(wèn)題  回復(fù)  更多評(píng)論   

# re: 安全的list[未登錄](méi) 2008-11-18 08:58 PeakGao

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

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

LZ的情況,我也遇到過(guò),困惑過(guò)。當(dāng)我看完jabberd2的代碼后,覺(jué)得它的做法比較好。

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

這樣做的好處,不會(huì)出現(xiàn)LZ這種list“重入”的問(wèn)題,而且可以靈活處理不需要的對(duì)象。  回復(fù)  更多評(píng)論   

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

頂樓上
mark it & lazy delete

這樣做在在邏輯上更為完整,相對(duì)于作者直接刪除對(duì)象而言
  回復(fù)  更多評(píng)論   

# re: 安全的list[未登錄](méi) 2008-11-20 13:35 PeakGao

@Jeff Chen
你這種其實(shí)就是我上面說(shuō)的這個(gè)意思:“再有一種辦法,就是對(duì)象要移除時(shí),只設(shè)置一個(gè)需要移除的標(biāo)志,在下一輪遍歷前才真正移除。”,不過(guò)你的說(shuō)法好像有問(wèn)題哦,遍歷時(shí)根本不知道是無(wú)效的Connection哦,而且不能在遍歷的過(guò)程中將節(jié)點(diǎn)移入到另一個(gè)列表,這樣會(huì)掛的  回復(fù)  更多評(píng)論   

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

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

<2007年10月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

留言簿(9)

隨筆分類(lèi)(67)

隨筆檔案(65)

搜索

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美精品激情在线观看| 久久在线免费视频| 久久午夜电影| 久热精品视频在线观看一区| 久久久久久久欧美精品| 欧美三级视频在线播放| 毛片一区二区三区| 久久久久一区二区三区四区| 久久免费视频一区| 欧美成年人在线观看| 欧美日韩小视频| 国内成人精品一区| 亚洲精品美女免费| 久久成人精品视频| 久久免费视频在线观看| 亚洲七七久久综合桃花剧情介绍| 亚洲电影成人| 先锋影音国产精品| 欧美日本中文字幕| 亚洲大胆人体视频| 久久久综合香蕉尹人综合网| 亚洲剧情一区二区| 久久精品人人做人人爽电影蜜月| 欧美日本中文| 日韩亚洲视频| 亚洲国产高清一区二区三区| 欧美一级在线视频| 国产精品女主播一区二区三区| 在线播放精品| 欧美一级淫片aaaaaaa视频| 亚洲黄色在线视频| 欧美国产成人精品| 91久久久久| 91久久久亚洲精品| 欧美激情一级片一区二区| 怡红院精品视频在线观看极品| 久久精品视频99| 久久国产精品久久久| 在线观看国产成人av片| 国产一区白浆| 久久综合五月| 老司机成人网| 亚洲精品五月天| 亚洲精品视频免费| 欧美性开放视频| 新片速递亚洲合集欧美合集 | 国产精品一区二区男女羞羞无遮挡| 在线精品国精品国产尤物884a| 欧美激情中文字幕一区二区| 欧美福利一区二区三区| 亚洲综合国产精品| 欧美一区二区视频97| 亚洲日本aⅴ片在线观看香蕉| 亚洲国内自拍| 国产在线高清精品| 亚洲毛片一区二区| 激情视频亚洲| 亚洲午夜三级在线| 日韩视频免费在线| 久久电影一区| 亚洲欧美日韩精品久久久久| 欧美激情aⅴ一区二区三区| 久久aⅴ国产欧美74aaa| 欧美日韩精品欧美日韩精品| 免费亚洲视频| 国产亚洲成年网址在线观看| 夜久久久久久| 亚洲乱码精品一二三四区日韩在线| 欧美在线短视频| 久久国产精品99国产| 国产精品美女久久久久久2018| 欧美福利小视频| 亚洲欧洲一区二区三区在线观看| 欧美在线一二三| 国产日本欧美一区二区| aⅴ色国产欧美| 亚洲先锋成人| 欧美视频一区在线| av不卡在线观看| 先锋影音一区二区三区| 国产精品综合| 久久色在线播放| 亚洲区国产区| 久久精品视频在线看| 伊人精品视频| 欧美精品日韩一区| 亚洲最新中文字幕| 欧美大胆成人| 亚洲一区二区视频在线观看| 国产精品久久久久久久久久久久久久| 一区二区三区日韩精品| 久久久综合网站| 中日韩在线视频| 黄色一区二区在线| 欧美日韩一区二区三区| 久久精品中文| 性久久久久久久| 中文成人激情娱乐网| 欧美日本韩国一区二区三区| 欧美一区二区三区四区在线| 日韩视频免费在线观看| 欧美成人免费在线| 久久久久久自在自线| 一区二区日韩精品| 亚洲七七久久综合桃花剧情介绍| 国产精品素人视频| 欧美体内谢she精2性欧美| 欧美高清不卡在线| 欧美成人午夜视频| 免费成人高清| 欧美成人免费在线观看| 六月婷婷久久| 欧美另类极品videosbest最新版本| 亚洲欧美制服中文字幕| 亚洲一区日韩| 亚洲小视频在线| 亚洲一区高清| 欧美一区二区三区喷汁尤物| 西瓜成人精品人成网站| 欧美一区二区三区四区在线| 欧美在线www| 欧美大片在线看免费观看| 欧美大学生性色视频| 最近看过的日韩成人| 这里只有精品丝袜| 欧美一级专区| 欧美—级在线免费片| 国产美女精品视频免费观看| 国产欧美精品一区aⅴ影院| 亚洲风情在线资源站| 一区二区日本视频| 欧美激情一区二区三区在线视频| 亚洲精品视频一区二区三区| 欧美一区二区视频在线| 欧美国产免费| 免费在线成人av| 亚洲欧美国产精品va在线观看 | 久久久久久久999| 美女诱惑一区| 国内综合精品午夜久久资源| 亚洲欧美激情视频在线观看一区二区三区| 久久精品国产一区二区电影| 亚洲精选视频在线| 久久午夜电影网| 狠狠色丁香久久综合频道| 一本色道久久88精品综合| 欧美激情va永久在线播放| 性亚洲最疯狂xxxx高清| 国产精品久久久久av| 亚洲欧美日韩国产精品| 亚洲午夜高清视频| 国产精品影视天天线| 亚洲小说欧美另类婷婷| 99精品国产一区二区青青牛奶| 欧美激情一二区| 久久理论片午夜琪琪电影网| 国产一区观看| 欧美成熟视频| 欧美日韩hd| 亚洲欧美日韩国产成人精品影院| 亚洲午夜免费视频| 国产日韩精品视频一区二区三区 | 亚洲欧洲在线看| 欧美激情1区2区3区| 欧美日韩国产美| 久久黄色网页| 欧美理论电影在线观看| 欧美综合国产精品久久丁香| 麻豆成人在线观看| 亚洲一区亚洲二区| 久久午夜色播影院免费高清| 在线亚洲精品| 久久人91精品久久久久久不卡| 亚洲精品久久久久中文字幕欢迎你| 亚洲精品一区二区三区婷婷月 | 午夜视频在线观看一区二区三区| 国产欧美日韩亚洲一区二区三区| 欧美高清在线精品一区| 国产一区二区三区成人欧美日韩在线观看 | 欧美日韩精品一区| 蜜臀久久99精品久久久久久9 | 亚洲国产欧美国产综合一区| 日韩网站在线看片你懂的| 国产一区二区三区成人欧美日韩在线观看 | 欧美暴力喷水在线| 久久国产一区| 国产欧美日韩三级| 亚洲图片激情小说| 亚洲男人天堂2024| 欧美日韩国产不卡| 欧美激情综合| 亚洲精品裸体| 欧美成人中文| 日韩视频亚洲视频| 欧美一区二区高清在线观看| 欧美午夜电影在线| 中文一区二区| 久久精品盗摄| 亚洲国产欧美一区二区三区久久 | 久久综合九色综合欧美狠狠|