国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

STL 注意事項(xiàng)

2019-11-11 00:27:43
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
STL中的容器的存儲(chǔ)分為順序存儲(chǔ)(如vector、deque)與鏈?zhǔn)酱鎯?chǔ)(如list、map、set)。對(duì)于map與list這樣的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。我們一般可以有兩種方法1. 使用erase(iter++),因?yàn)閕ter2 = iter++是iter先移到指向下一個(gè)節(jié)點(diǎn),而iter2還是指向當(dāng)前的節(jié)點(diǎn)。for(;iter!=mapStudent.end();){     if((iter->second)>=aa)     {         //滿足刪除條件,刪除當(dāng)前結(jié)點(diǎn),并指向下面一個(gè)結(jié)點(diǎn)              mapStudent.erase(iter++);     }     else     {     //條件不滿足,指向下面一個(gè)結(jié)點(diǎn)     iter++;     }}這種刪除方式也是STL源碼一書中推薦的方式,分析 mapStudent.erase(iter++)語(yǔ)句,map中在刪除iter的時(shí)候,先將iter做緩存,然后執(zhí)行iter++使之指向下一個(gè)結(jié)點(diǎn),再進(jìn)入erase函數(shù)體中執(zhí)行刪除操作,刪除時(shí)使用的iter就是緩存下來(lái)的iter(也就是當(dāng)前iter(做了加操作之后的iter)所指向結(jié)點(diǎn)的上一個(gè)結(jié)點(diǎn))。    根據(jù)以上分析,可以看出mapStudent.erase(iter++)和map Student.erase(iter); iter++;這個(gè)執(zhí)行序列是不相同的。前者在erase執(zhí)行前進(jìn)行了加操作,在iter被刪除(失效)前進(jìn)行了加操作,是安全的;后者是在erase執(zhí)行后才進(jìn)行加操作,而此時(shí)iter已經(jīng)被刪除(當(dāng)前的迭代器已經(jīng)失效了),對(duì)一個(gè)已經(jīng)失效的迭代器進(jìn)行加操作,行為是不可預(yù)期的,這種寫法勢(shì)必會(huì)導(dǎo)致 map操作的失敗并引起進(jìn)程的異常。2. erase的返回值會(huì)指向下一個(gè)節(jié)點(diǎn)    for(TStrMapIter iter= strmap.begin(); iter!= strmap.end();)      {         if ("somevalue" == iter->second )         {           iter = strmap.erase(iter);         }         else         {           ++iter;         }      }  但對(duì)于順序存儲(chǔ)第一種用法卻是錯(cuò)誤的。因?yàn)轫樞虼鎯?chǔ)的容器一旦erase時(shí),會(huì)涉及到數(shù)據(jù)移動(dòng),iterator所指的位置還是那個(gè)位置,但元素卻移動(dòng)了,iter++之后已不再你想要的元素位置了。iter = strmap.erase(iter)與iter++對(duì)于順序容器有何不同?源碼剖析以STL list為例:iterator的相關(guān)操作_Self& Operator++(){    this->_M_incr();    return *this;}_Self operator++(int){    _Self __tmp = *this;    this->_M_incr();    return __tmp;               //后綴++按照語(yǔ)意返回了++前的iterator,}void _M_incr() { _M_node = _M_node->_M_next; }    //++的操作對(duì)于list結(jié)構(gòu)來(lái)說(shuō),就是使iterator的_M_node指向下一個(gè)結(jié)點(diǎn)iterator erase(iterator __position){   _List_node_base* __next_node = __position._M_node->_M_next;    _List_node_base* __PRev_node = __position._M_node->_M_prev;    _Node* __n = (_Node*) __position._M_node;    __prev_node->_M_next = __next_node;    __next_node->_M_prev = __prev_node;  //上面的代碼把刪除結(jié)點(diǎn)__position的前后結(jié)點(diǎn)串起來(lái),而移除_positoin    _STLP_STD::_Destroy(&__n->_M_data); //call T::~T()    this->_M_node.deallocate(__n, 1);            //釋放結(jié)點(diǎn)內(nèi)存    return iterator((_Node*)__next_node);}分析代碼我們可以看出,erase會(huì)deallocate__position的_M_node, 在__position上再進(jìn)行++是錯(cuò)誤的。所以不能在m_list.erase(iter)后,進(jìn)行iter++.哪為什么m_list.erase(iter++)可以呢?為什么不能用m_list.erase(++iter)?參照operator++的代碼我們可以找到答案,iter++返回了++之前的iter值,erase使用這個(gè)值能正確進(jìn)行__position的前后結(jié)點(diǎn)的串接及刪除正確的結(jié)點(diǎn),而++iter返回的是++之后的iter,所以m_list.erase(++iter)串接不正確,iter->_M_node也是失效的.對(duì)于非結(jié)點(diǎn)類,如數(shù)組類的容器vector,string,deque,如果erase會(huì)返回下個(gè)有效的iterator,可以這樣處理:for(vector<int>::iterator iter = m_vector.begin(); iter != m_vector.end();){    if(需要?jiǎng)h除)    {        iter=m_vector.erase(iter);    }    else        ++iter;}
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 靖安县| 南京市| 寻甸| 阿拉善右旗| 青阳县| 依安县| 昌吉市| 信丰县| 天柱县| 辛集市| 永清县| 克什克腾旗| 安康市| 怀仁县| 洛浦县| 东乡| 枣庄市| 突泉县| 墨脱县| 浦北县| 印江| 萝北县| 宜阳县| 剑河县| 泾川县| 桃园市| 徐闻县| 宜州市| 灵璧县| 苍山县| 衢州市| 金寨县| 体育| 乌鲁木齐市| 交城县| 普兰县| 巴林左旗| 民县| 黎川县| 临安市| 桃江县|