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

首頁 > 學院 > 開發設計 > 正文

STL 注意事項

2019-11-10 22:08:47
字體:
來源:轉載
供稿:網友
STL中的容器的存儲分為順序存儲(如vector、deque)與鏈式存儲(如list、map、set)。對于map與list這樣的鏈式存儲結構。我們一般可以有兩種方法1. 使用erase(iter++),因為iter2 = iter++是iter先移到指向下一個節點,而iter2還是指向當前的節點。for(;iter!=mapStudent.end();){     if((iter->second)>=aa)     {         //滿足刪除條件,刪除當前結點,并指向下面一個結點              mapStudent.erase(iter++);     }     else     {     //條件不滿足,指向下面一個結點     iter++;     }}這種刪除方式也是STL源碼一書中推薦的方式,分析 mapStudent.erase(iter++)語句,map中在刪除iter的時候,先將iter做緩存,然后執行iter++使之指向下一個結點,再進入erase函數體中執行刪除操作,刪除時使用的iter就是緩存下來的iter(也就是當前iter(做了加操作之后的iter)所指向結點的上一個結點)。    根據以上分析,可以看出mapStudent.erase(iter++)和map Student.erase(iter); iter++;這個執行序列是不相同的。前者在erase執行前進行了加操作,在iter被刪除(失效)前進行了加操作,是安全的;后者是在erase執行后才進行加操作,而此時iter已經被刪除(當前的迭代器已經失效了),對一個已經失效的迭代器進行加操作,行為是不可預期的,這種寫法勢必會導致 map操作的失敗并引起進程的異常。2. erase的返回值會指向下一個節點    for(TStrMapIter iter= strmap.begin(); iter!= strmap.end();)      {         if ("somevalue" == iter->second )         {           iter = strmap.erase(iter);         }         else         {           ++iter;         }      }  但對于順序存儲第一種用法卻是錯誤的。因為順序存儲的容器一旦erase時,會涉及到數據移動,iterator所指的位置還是那個位置,但元素卻移動了,iter++之后已不再你想要的元素位置了。iter = strmap.erase(iter)與iter++對于順序容器有何不同?源碼剖析以STL list為例:iterator的相關操作_Self& Operator++(){    this->_M_incr();    return *this;}_Self operator++(int){    _Self __tmp = *this;    this->_M_incr();    return __tmp;               //后綴++按照語意返回了++前的iterator,}void _M_incr() { _M_node = _M_node->_M_next; }    //++的操作對于list結構來說,就是使iterator的_M_node指向下一個結點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;  //上面的代碼把刪除結點__position的前后結點串起來,而移除_positoin    _STLP_STD::_Destroy(&__n->_M_data); //call T::~T()    this->_M_node.deallocate(__n, 1);            //釋放結點內存    return iterator((_Node*)__next_node);}分析代碼我們可以看出,erase會deallocate__position的_M_node, 在__position上再進行++是錯誤的。所以不能在m_list.erase(iter)后,進行iter++.哪為什么m_list.erase(iter++)可以呢?為什么不能用m_list.erase(++iter)?參照operator++的代碼我們可以找到答案,iter++返回了++之前的iter值,erase使用這個值能正確進行__position的前后結點的串接及刪除正確的結點,而++iter返回的是++之后的iter,所以m_list.erase(++iter)串接不正確,iter->_M_node也是失效的.對于非結點類,如數組類的容器vector,string,deque,如果erase會返回下個有效的iterator,可以這樣處理:for(vector<int>::iterator iter = m_vector.begin(); iter != m_vector.end();){    if(需要刪除)    {        iter=m_vector.erase(iter);    }    else        ++iter;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 津市市| 九龙坡区| 普格县| 布尔津县| 五原县| 金秀| 阜阳市| 手游| 偏关县| 桑日县| 高安市| 鄄城县| 长寿区| 嘉祥县| 沙田区| 来宾市| 云霄县| 东莞市| 桂东县| 阿城市| 吴旗县| 宣恩县| 弥渡县| 夏河县| 黄平县| 凌云县| 谢通门县| 香港| 安康市| 松溪县| 镶黄旗| 绥芬河市| 新丰县| 灵宝市| 永定县| 永年县| 南岸区| 石城县| 庆阳市| 乌拉特中旗| 西藏|