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

posts - 297,  comments - 15,  trackbacks - 0

    在STL(標準模板庫)中經常會碰到要刪除容器中部分元素的情況,本人在編程中就經常編寫這方面的代碼,在編碼和測試過程中發現在STL中刪除容器有很多陷阱,網上也有不少網友提到如何在STL中安全刪除元素這些問題。本文將討論編程過程中最經常使用的兩個序列式容器vector、list中安全刪除元素的方法和應該注意的問題,       其它如queue、stack等配接器容器(container adapter),由于它們有專屬的操作行為,沒有迭代器(iterator),不能采用本文介紹的刪除方法,至于deque,它與vector的刪除方法一樣。STL容器功能強大,but no siliver bullet,如果你使用不當,也將讓你吃盡苦頭。
    這里最重要的是要理解erase成員函數,它刪除了itVect迭代器指向的元素,并且返回要被刪除的itVect之后的迭代器,迭代器相當于一個智能指 針,指向容器中的元素,現在刪除了這個元素,將導致內存重新分配,相應指向這個元素的迭代器之后的迭代器就失效了,但erase成員函數返回要被刪除的 itVect之后的迭代器。

1.手工編寫for循環代碼刪除STL序列式容器中元素的方法
例如,你能看出以下代碼有什么問題?
例1:
#include <iostream>
#include <vector>
using namespace std;
void main( ) {
       vector<int> vectInt;
       int i;
       //     初始化vector容器
       for (i = 0; i < 5; i++ ) {
               vectInt.push_back( i );
       }
       //     以下代碼是要刪除所有值為4的元素
       vector<int>::iterator itVect = vectInt.begin();
       for ( ; itVect != vectInt.end();   ++itVect ) {
               if ( *itVect == 4 ) {
                     vectInt.erase( itVect );
               }
       }
       int iSize = vectInt.size();
       for (   i = 0 ; i < iSize; i++ )   {
                     cout << " i= " << i <<   ", " << vectInt[ i ] << endl;
       }
}

    例1將導致程序未定義的錯誤,在windows中即是訪問非法內存,程序當掉。因為vectInt.erase( itVect );調用后itVect之后的迭代器已無效了,所以當執行++itVect后,*itVect訪問了非法內存。例1也是初學者最容易犯的錯誤,這個錯誤也 比較容易發現。

例2:
#include <iostream>
#include <vector>
using namespace std;
void main( ) {
       vector<int> vectInt;
       int i;
       //     初始化vector容器
       for ( i = 0; i < 5; i++ ) {
               vectInt.push_back( i );
               if ( 3 == i ) {
                     //       使3的元素有兩個,并且相臨。這非常關鍵,否則將發現不了bug。
                     //   具體解釋見下。
                     vectInt.push_back( i );
               }
       }
       vector<int>::iterator itVect = vectInt.begin();
       vector<int>::iterator itVectEnd = vectInt.end(); //       防止for多重計算
       //     以下代碼是要刪除所有值為3的元素
       for ( ; itVect != itVectEnd; ++itVect ) {
               if ( *itVect == 3 ) {
                     itVect = vectInt.erase( itVect );
               }
       }
       int iSize = vectInt.size();
       for (   i = 0 ; i < iSize; i++ )   {
                     cout << " i= " << i <<   ", " << vectInt[ i ] << endl;
       }

例2可能會導致不能把vectInt中所有為3的元素刪除掉。因為第一次刪除成功時,itVect = vectInt.erase( itVect );itVect為指向3之后的位置,之后再執行++itVect,itVect就掉過了被刪除元素3之后的元素3,導致只刪除了一個為3的元素,這個 bug比較隱蔽,因為如果不是兩個均為3的元素相臨,就將很難捕捉到這個bug,程序有可能在一段時間運行良好,但如碰到容器中兩值相同的元素相臨,則程 序就要出問題。


例3:
#include <iostream>
#include <vector>
using namespace std;
void main( ) {
       vector<int> vectInt( 5 );
       int i;
       vectInt[ 0 ] = 0;
       vectInt[ 1 ] = 1;
       vectInt[ 2 ] = 2;
       vectInt[ 3 ] = 3;
       vectInt[ 4 ] = 4; //     替換為 vectInt[ 4 ] = 3;試試
       vector<int>::iterator itVect = vectInt.begin();
       vector<int>::iterator itVectEnd = vectInt.end(); //       防止for多重計算
       //     以下代碼是要刪除所有值為3的元素
       for ( ; itVect != itVectEnd; ) {
               if ( *itVect == 3 ) {
                     itVect = vectInt.erase( itVect );
               }
               else {
                     ++itVect;
               }
       }
       int iSize = vectInt.size();
       for (   i = 0 ; i < iSize; i++ )   {
                     cout << " i= " << i <<   ", " << vectInt[ i ] << endl;
       }
}
例3,對于本例你可能要說程序沒有任何問題,解決了上面的兩個bug,程序也運行正常。但且慢,你把 “vectInt[ 4 ] = 4;” 這一行改為 “vectInt[ 4 ] = 3;”試試,一運行,程序當掉,訪問非法內存!你疑惑不解:從程序看不出bug,而且我還把vectInt.end()放在外面計算以防止for多重計算,提高效率。哈哈,問題就出在最后一句話!算法大師Donald Knuth有一句名言:不成熟的優化是一切惡果的根源( Permature optimization is the root of all evil )。由于在for循環中要刪除元素,則vectInt.end()是會變化的,所以不能在for循環外計算,而是每刪除一次都要重新計算,所以應放在 for循環內。那你要問,為什么把 “vectInt[ 4 ] = 4;” 這一行改為 “vectInt[ 4 ] = 3;”程序就會當掉,而不改程序就很正常呢?這就跟vector的實現機制有關了。下面以圖例詳細解釋。
vectInt的初始狀態為:

                                  | end
0   1   2   3   4                                  

刪除3后,

                       |新的end   | 原來的end
0   1   2   4   4    


注意上面“新的end”指向的內存并沒有被清除,為了效率,vector會申請超過需要的內存保存數據,刪除數據時也不會把多余的內存刪除。

然后itVect再執行++itVect,因為此時*itVect等于4,所以繼續循環, 這時itVect 等于“新的end”但不等于“原來的end”(它即為itVectEnd),所以繼續,因為 *itVect訪問的是只讀內存得到的值為4,不等于3,故不刪除,然后執行++itVect此時itVect等于itVectEnd退出循環。從上面過程可以看出,程序多循環了一次(刪除幾次,就要多循環幾次),但程序正常運行。

如果把 “vectInt[ 4 ] = 4;” 這一行改為 “vectInt[ 4 ] = 3;”過程如下:

                                                                         | end
0         1         2         3         3    

  
刪除3后,
                                                                 |新的end       |原來的 end
0         1         2         3         3      

刪除第2個3后,
                                                 |新的end             |原來的 end
0         1         2         3         3      

這時itVect 等于“新的end”但不等于“原來的end”(它即為itVectEnd),所以繼續,因為 *itVect訪問的是只讀內存得到的值為3,等于3,所以執行刪除,但因為*itVect訪問的是只讀內存不能刪除,所以程序當掉。

綜上,我們知道當要刪除的值在容器末尾時,會導致程序刪除非法內存,程序當掉;即使程序正常運行,也是for循環多執行了等于刪除個數的循環。所以把 vectInt.end()放在for循環外面執行,完全是錯誤的。對于list容器,list.end()在刪除過程中是不會變的,可以把它放在for 循環外面計算,但由于list.end()是個常量,把list.end()放在for循環中計算編譯器應該可以優化它。從安全考慮,除非你能保證for 循環中不會改變容器的大小,否則都應該對容器的值在for循環中計算,對于 vectInt.size()這樣的計算,也應該在for循環中計算,不要因為微小的優化而導致程序出錯。


正確的方法:
例4:
#include <iostream>
#include <vector>
using namespace std;
void main( ) {
       vector<int> vectInt;
       int i;
       for (   i = 0; i < 5; i++ ) {
               vectInt.push_back( i );
               if ( 3 == i ) {
                     //       使3的元素有兩個,并且相臨。
                     vectInt.push_back( i );
               }
       }
       vector<int>::iterator itVect = vectInt.begin();

       //     以下代碼是要刪除所有值為3的元素

       for ( ; itVect != vectInt.end();   ) {   // 刪除 ++itVect{

               if ( *itVect == 3 ) {

                     itVect = vectInt.erase( itVect );
               }
               else {

                     ++itVect;
               }
       }
       //     把vectInt.size()放在for循環中

       for (   i = 0 ; i < vectInt.size(); i++ )   {
                     cout << " i= " << i <<   ", " << vectInt[ i ] << endl;
       }

運行結果為:
i= 0, 0
i= 1, 1
i= 2, 2
i= 3, 4

從結果顯示值為3的元素確實被刪除了。

2.使用STL中通用算法或容器成員函數刪除元素的方法
以上手工編寫for循環代碼刪除容器中元素的方法也有一些問題,如果判斷條件特別復雜,又有循環判斷的話,循環中間又有異常處理的話,++itVect的位置就要小心放置了,稍不留意就要出錯。所以手工編寫代碼刪除容器中元素的方法不太安全,代碼重復,也不夠優雅,要注意的地方很多。

對于這種情況,可以考慮使用STL中通用算法remvoe()和remove_if()幫忙。而remvoe()和remove_if()這兩個算法也有一個問題需要程序員特別小心。在通用算法中的 remove(包括remove_if)函數,并不真正從容器中刪除元素,而是“應被刪除的元素”被其后的“未被刪除的元素”覆蓋。返回值ForwardIterator指向經移除后的最后元素的下一位置。如vector{0,1,2,3,3,4},執行remove(),希望移除所有值為3的元素,結果為{0,1,2,4,3,4},返回值 ForwardIterator指向第5個元素。即:

0         1         2         3         3       4   移除前

0         1         2         4         3       4   移除后


移除值為3的元素。移除后3被其后的4替代,最后兩位元素為殘余數據。

例 5:

void main() {
       vector<int> vectInt;
       int i;
       for (i = 0; i < 5; i++ ) {
               vectInt.push_back( i );
               if ( 3 == i ) {
                     vectInt.push_back( i );
               }
       }
       remove( vectInt.begin(), vectInt.end(), 3 );
       cout << " after deleted , size = " << vectInt.size() << endl;
       for ( i = 0; i < vectInt.size();; i++ ) {
               cout << "i = " << i << " , " << vectInt[i] << endl;
       }
}
運行結果為:
after deleted , size = 6 // 從這行可以看出,移除后容器的大小沒變
i = 0 , 0
i = 1 , 1
i = 2 , 2
i = 3 , 4 //   從這行可以看出:“應被刪除的元素”3 被其后的“未被刪除的元素”4覆蓋
i = 4 , 3
i = 5 , 4    

所以要徹底刪除還應該把后面的殘余數據刪除掉,這可以通過調用容器的成員函數erase()做到。

例 6:
void main() {
       vector<int> vectInt;
       int i;
       for (i = 0; i < 5; i++ ) {
               vectInt.push_back( i );
               if ( 3 == i ) {
                     vectInt.push_back( i );
               }
       }
       vectInt.erase( remove( vectInt.begin(), vectInt.end(), 3 ), vectInt.end() );
       cout << " after deleted , size = " << vectInt.size() << endl;
       for ( i = 0; i < vectInt.size();; i++ ) {
               cout << "i = " << i << " , " << vectInt[i] << endl;
       }
}

運行結果為:
after deleted , size = 4 // 從這行可以看出,刪除后容器的大小變化了
i = 0 , 0
i = 1 , 1
i = 2 , 2
i = 3 , 4
從結果可以看出,所有值為3的元素確實被刪除了。
對于vector容器存放其他比較復雜的對象,就可以用remove_if()加函數對象(Function Object)的方法。
如:
例7:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;
class CTest {
public:
       CTest( const string& str, int iPrice ) : m_strName( str ), m_iPrice( iPrice ) { }
       void vPrint() { cout << "name=" << m_strName << " price = " << m_iPrice << endl;
       }
private:
       string m_strName;
       int   m_iPrice;
       //     由于兩個函數對象要訪問CTest類的private成員,所以設為友員。
       friend class CStrFunc;
       friend class CIntFunc;
};

//     函數對象,根據string比較
class CStrFunc {
       string m_str;
public:
       CStrFunc( const string& str ) : m_str( str ) {
       }
       bool operator() ( const CTest& left ) {
               return ( m_str == left.m_strName ) ? true : false;
       }
};

//     函數對象,根據int比較
class CIntFunc {
       int m_iPrice;
public:
       CIntFunc( int iPrice ) : m_iPrice( iPrice ) {
       }
       bool operator() ( const CTest& left ) {
               return ( m_iPrice == left.m_iPrice ) ? true : false;
       }
};

void main( ) {

       vector< CTest > vectTest;
       int i;
       for (   i = 0; i < 5 ; i++ ) {
               stringstream stream; //       流格式化符,把int轉化為string
               stream << i;
               string str = stream.str();
               CTest clTest( str, i );
               vectTest.push_back( clTest );
       }
       for (   i = 0 ; i < vectTest.size(); i++ )   {
               vectTest[ i ].vPrint();
       }
       //     刪除所有m_strName = "3"的元素
       vectTest.erase( remove_if( vectTest.begin(), vectTest.end(), CStrFunc( "3" ) ),
               vectTest.end() );
       cout << "delete 3 after : " << endl;
       for (   i = 0 ; i < vectTest.size(); i++ )   {
               vectTest[ i ].vPrint();
       }
       //     刪除所有m_iPrice = 2的元素
       vectTest.erase( remove_if( vectTest.begin(), vectTest.end(), CIntFunc( 2 ) ),
               vectTest.end() );
       cout << "delete 2 after : " << endl;
       for (   i = 0 ; i < vectTest.size(); i++ )   {
               vectTest[ i ].vPrint();
       }
}
手工編寫for循環代碼刪除STL序列式容器中元素的方法,使用STL中通用算法或容器成員函數刪除元素的方法,兩者之間的比較:
1.   前者代碼重復。
2.   前者容易出錯,不夠清晰。
3.   效率:
0                   1           2       3                 2           5       6                 7
0                   1           3       2                 5           6       7
0                   1           3       5                 6           7
用第一種方法刪除所有值為2的元素
從上圖可以看出,每刪除一個元素,后面的所有元素都到往前移動一位,導致一次內存大搬遷。

0                   1           2       3                 2           5       6                 7
0                   1           3       2                 5           6       6                 7
0                   1           3       5                 6           7

用第二種方法刪除所有值為2的元素
從上面可以看出,刪除時元素2被后面元素覆蓋,不會到元素移位和內存大搬遷,殘余數據留到末尾一次全部刪除,也不會導致內存大搬遷,所以后者的方法要比前者在效率上好很多。 

3.list容器中刪除元素的方法
對于list容器,由于list本身有remove和remove_if的成員函數,所以最好優先考慮list自己的算法,對于remove函數,比較簡單,不再討論,對于remove_if函數,本人發現在vc6.0中有重大問題。我試了多種函數對象,總是編譯不過,通過查看源代碼,才發現VC6.0中對remove_if()函數作了簡化,只提供了一種比較函數,它只能刪除不等于某值的元素,VC6.0種remove_if()函數的源碼如下:
typedef binder2nd<not_equal_to<_Ty> > _Pr1;
       void remove_if(_Pr1 _Pr)
               {iterator _L = end();
               for (iterator _F = begin(); _F != _L; )
                     if (_Pr(*_F))
                             erase(_F++);
                     else
                             ++_F; }
從源碼中可以看出,remove_if中_Pr1函數對象被固定為binder2nd<not_equal_to<_Ty> >一種格式。而在VC7.0中已經修改了這個bug,源碼如下:
template<class _Pr1>
               void remove_if(_Pr1 _Pred)
               {     // erase each element satisfying _Pr1
               iterator _Last = end();
               for (iterator _First = begin(); _First != _Last; )
                     if (_Pred(*_First))
                             erase(_First++);
                     else
                             ++_First;
               }
在VC7.0中remove_if()是成員模板函數,可以用任何判斷條件的函數對象。
例如:
例 8:
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
class CTest{
public:
       CTest( int i ) : m_iPrice ( i ) {     }
       int operator == ( const CTest& right ) const{
               return ( m_iPrice == right.m_iPrice ) ? 1 : 0;
       }
       int operator != ( const CTest& right ) const{
               return ( m_iPrice != right.m_iPrice ) ? 1 : 0;
       }
       int operator < ( const CTest& right ) const {
               return ( m_iPrice < right.m_iPrice ) ? 1 : 0;
       }
private:
       int m_iPrice;
       friend class CTestFunc;
};
class CTestFunc {             //       函數對象
public:
       int m_value;
       CTestFunc( int i ) : m_value( i ) {}
       bool operator () ( const CTest& clFirst ) {
               return ( clFirst.m_iPrice == m_value ) ? true : false;     }
};
void main() {
       list< CTest > listTest;
       for ( int i = 0; i < 5; i++ ) {
               CTest clTest( i );
               listTest.push_back( clTest );
       }
       cout << "remove before : " << listTest.size() << endl;
//     刪除所有為2的元素
       listTest.remove_if( CTestFunc( 2 )   ); //       這條語句在vc6.0中不能編譯通過,VC7.0中可以
       cout << "remove after : 2, size =   " << listTest.size() << endl;

       //     刪除所以不等于2的元素,VC6.0中只能以這種方式調用remove_if()函數
       listTest.remove_if(   bind2nd( not_equal_to<CTest>(), 2 )     );
       cout << "remove after not equal to 2, size =   " << listTest.size() << endl;

       //     因為CTest類提供了==、< 成員函數,所以也可以用remove函數
       listTest.remove( 2 ); //       刪除所有為2的元素
       cout << "remove after : 2, size =   " << listTest.size() << endl;
}

不知道在VC6.0中能否突破只能函數對象被固定為binder2nd<not_equal_to<_Ty> >一種格式的限制?歡迎諸位大蝦不吝賜教。不過采用通用算法remove_if只是多了幾次對象的賦值的負擔,如果對象不是太大,用通用算法的性能也是可以接受的。

另外,這些天使用了VC7.0后,感覺非常棒,不僅幾乎符合Standard C++規范,錯誤提示也更清晰,而編譯速度和編譯后的文件大小大大減小,如我原來的一個大量使用了模板的程序,用VC6.0編譯后Release版的可執行文件大小為1.2M,用VC7.0編譯后只有420K,我想可能VC7.0在代碼優化和模板代碼的膨脹等方面有了極大的改善;在STL的實現上也有了極大的改進,把原來的一些效率不好的地方都改進了,處理策略基本與SGI STL一致。

4.STL容器中元素為指針情況下的刪除方法
對于容器中的元素為指針的刪除方法。如果容器中的元素為指針則不能用上面介紹的用通過算法或成員函數的方法刪除元素,因為那樣做會導致內存泄露,容器中的元素為指針指向的內存沒有釋放,在這種情況下有以下方法解決:

1.   盡可能不用指針作為容器的元素。

2.   如果是因為要減少對象拷貝和賦值方面的負擔,而要在容器中存放指針的話,可以考慮用boost庫中的智能指針shared_ptr包裝指針,達到容器中引用的語意。

3.   如果你不希望因為使用boost::shared_ptr增加引用計數的負擔,認為引入智能指針不好理解,那么你用指針作為容器的元素要千萬小心,這時你要自己管理內存。

例如:    

例 9:用boost庫中的智能指針shared_ptr包裝指針的例子:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <list>
#include <boost\smart_ptr.hpp> // 要包含BOOST類庫中智能指針的頭文件
using namespace std;
class CTest {
public:
       CTest( const string& str, int iPrice ) : m_strName( str ), m_iPrice( iPrice ) { }
       void vPrint() { cout << "name=" << m_strName << " price = " << m_iPrice << endl;
       }

private:
       string m_strName;
       int   m_iPrice;
       friend class CStrFunc;
       friend class CIntFunc;
};

//     函數對象,根據string比較
class CStrFunc {
       string m_str;

public:
       CStrFunc( const string& str ) : m_str( str ) {
       }
       //     此處要改為boost::shared_ptr<CTest>&,因為vector容器中的元素為
//       boost::shared_ptr<CTest>
       bool operator() ( const boost::shared_ptr<CTest>& left ) {
               return ( m_str == (*left).m_strName ) ? true : false;
       }

};

//     函數對象,根據int比較
class CIntFunc {
       int m_iPrice;
public:
       CIntFunc( int iPrice ) : m_iPrice( iPrice ) {
       }
//     此處要改為boost::shared_ptr<CTest>&,因為vector容器中的元素為
//       boost::shared_ptr<CTest>
       bool operator() ( const boost::shared_ptr<CTest>& left ) {
               return ( m_iPrice == (*left).m_iPrice ) ? true : false;
       }
};
void main( ) {

       vector< boost::shared_ptr<CTest>   > vectTest;
       int i;
       for (   i = 0; i < 5 ; i++ ) {
               stringstream stream;
               stream << i;
               string str = stream.str();
               boost::shared_ptr<CTest>   ptrShare( new CTest( str, i ) );
               vectTest.push_back( ptrShare );
       }
       for (   i = 0 ; i < vectTest.size(); i++ )   {
               ( *vectTest[ i ] ).vPrint();
       }
       //     刪除所有m_strName = "3"的元素
       vectTest.erase( remove_if( vectTest.begin(), vectTest.end(), CStrFunc( "3" ) ),
               vectTest.end() );
       cout << "delete 3 after : " << endl;
       for (   i = 0 ; i < vectTest.size(); i++ )   {
               ( *vectTest[ i ] ).vPrint();
       }
       //     刪除所有m_iPrice = 2的元素
       vectTest.erase( remove_if( vectTest.begin(), vectTest.end(), CIntFunc( 2 ) ),
               vectTest.end() );
       cout << "delete 2 after : " << endl;
       for (   i = 0 ; i < vectTest.size(); i++ )   {
               ( *vectTest[ i ] ).vPrint();
       }
}

以上代碼不會導致內存泄露。

例 10:自己編程刪除容器中元素為指針的例子:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class CTest {
public:
       CTest( const string& str, int iPrice ) : m_strName( str ), m_iPrice( iPrice ) { }
       void vPrint() { cout << "name=" << m_strName << " price = " << m_iPrice << endl;
       }
private:
       string m_strName;
       int   m_iPrice;
       //     聲明友員函數,因為vDeleteVector函數要訪問CTest的private成員變量
       friend void vDeleteVector( vector< CTest*   >& vectTest, const string& str );
       friend void vDeleteVector( vector< CTest*   >& vectTest, int iPrice );
};
//     根據CTest類中m_strName比較
void vDeleteVector( vector< CTest*   >& vectTest, const string& str ) {
       vector< CTest* >::iterator itVect = vectTest.begin();
       for ( ; itVect != vectTest.end();; ) {
               if ( (*itVect)->m_strName == str ) {
                     //       刪除vector容器中指針元素指向的內容,防止內存泄露
                     delete *itVect;
                     itVect = vectTest.erase( itVect );
               }
               else {
                     ++itVect;
               }
       }
}
//     根據CTest類中m_iPrice比較
void vDeleteVector( vector< CTest*   >& vectTest, int iPrice ) {
       vector< CTest* >::iterator itVect = vectTest.begin();
       for ( ; itVect != vectTest.end(); ) {
               if ( (*itVect)->m_iPrice == iPrice ) {
                     //       刪除vector容器中指針元素指向的內容,防止內存泄露
                     delete *itVect;
                     itVect = vectTest.erase( itVect );
               }
               else {
                     ++itVect;
               }
       }
}

void main( ) {
       vector< CTest*   > vectTest;
       int i;
       for (   i = 0; i < 5 ; i++ ) {
               stringstream stream;
               stream << i;
               string str = stream.str();
               CTest* pclTest =   new CTest( str, i ) ;
               vectTest.push_back( pclTest );
       }
       for (   i = 0 ; i < vectTest.size(); i++ )   {
               vectTest[ i ]->vPrint();
       }
       //     刪除所有m_strName = "5"的元素
       vDeleteVector( vectTest, "3" );
       cout << "delete 3 after : " << endl;
       for (   i = 0 ; i < vectTest.size(); i++ )   {
               vectTest[ i ]->vPrint();
       }
       //     刪除所有m_iPrice = 2的元素
       vDeleteVector( vectTest, 2 );
       cout << "delete 2 after : " << endl;
       for (   i = 0 ; i < vectTest.size(); i++ )   {
               vectTest[ i ]->vPrint();
       }
}
原則:
1.   盡可能用通用算法。相信STL的算法要比自己的實現高效、優雅、安全。
2.   優先用容器自身的成員函數。 見《Effective STL》中 Item 44: Prefer member functions to algorithms with the same names
3.   盡可能熟悉函數對象。
4.   多看STL的源碼,了解其實作。
5.   不成熟的優化是一切惡果的根源。編寫代碼,安全第一。
綜上,在STL中刪除容器中部分元素時要特別小心,不過通過使用通用算法或容器本身的刪除函數,能大大減小重復代碼和程序出錯的機會,能夠使代碼得到優化,生成高效的代碼。

posted on 2008-07-09 22:32 chatler 閱讀(2205) 評論(0)  編輯 收藏 引用 所屬分類: GP_STL
<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久久国产免费免费| 亚洲精品小视频在线观看| 欧美日韩国产va另类| 久久免费观看视频| 国产精品国产成人国产三级| 亚洲第一福利视频| 国模大胆一区二区三区| 亚洲一区二区三区欧美| 9久草视频在线视频精品| 免费观看成人鲁鲁鲁鲁鲁视频| 久久久久久香蕉网| 国产日产欧产精品推荐色 | 性欧美激情精品| 午夜精品999| 欧美小视频在线| 中日韩美女免费视频网站在线观看| 99精品国产在热久久| 欧美精品色一区二区三区| 亚洲国产精品999| 亚洲精品视频一区二区三区| 免费短视频成人日韩| 亚洲成人资源| 日韩一区二区精品视频| 欧美精品一区二区三区一线天视频| 欧美激情精品久久久六区热门| 亚洲成人原创| 免费成人av在线| 亚洲激情自拍| 亚洲中午字幕| 国产精品一区二区a| 欧美一区二粉嫩精品国产一线天| 久久爱另类一区二区小说| 国产日韩在线亚洲字幕中文| 欧美夜福利tv在线| 嫩草影视亚洲| 亚洲精品欧美精品| 欧美日韩中文字幕在线视频| 亚洲一区二区三区四区中文| 欧美中文在线字幕| 在线日韩欧美| 欧美日韩精品综合| 午夜在线精品偷拍| 欧美电影免费观看网站| 9久草视频在线视频精品| 国产精品久久久久永久免费观看| 午夜欧美精品久久久久久久| 久热爱精品视频线路一| 夜夜嗨av一区二区三区四季av| 国产精品久久久久影院亚瑟| 欧美一区亚洲一区| 亚洲国产欧美国产综合一区 | 久久在线免费| 亚洲精品五月天| 国产精品任我爽爆在线播放 | 一区二区三区高清| 国产日产高清欧美一区二区三区| 久久网站免费| av成人天堂| 久久婷婷综合激情| 亚洲午夜在线视频| 在线观看日韩av电影| 亚洲精品黄网在线观看| 在线看国产一区| 欧美日韩免费在线观看| 欧美亚洲专区| 亚洲精品综合精品自拍| 久久久久久久久岛国免费| 99国产精品久久久久久久成人热| 国产日韩欧美二区| 欧美精品在线一区二区| 久久精品人人做人人爽| 正在播放日韩| 亚洲二区免费| 久久先锋影音av| 午夜精品福利一区二区蜜股av| 91久久在线播放| 国产一区二区高清| 国产精品二区二区三区| 欧美精品18+| 老巨人导航500精品| 午夜久久tv| 亚洲精品在线视频观看| 国产亚洲福利一区| 欧美私人网站| 欧美日韩国产系列| 欧美成人一区在线| 久久久久se| 欧美亚洲在线观看| 亚洲制服少妇| 亚洲一级网站| 99这里只有久久精品视频| 亚洲福利av| 欧美大片18| 欧美高清在线观看| 免费在线欧美黄色| 另类激情亚洲| 久久频这里精品99香蕉| 久久精品免费观看| 久久精品国产综合| 久久精品日产第一区二区三区| 亚洲欧美在线aaa| 亚洲一区久久| 亚洲免费影院| 性伦欧美刺激片在线观看| 午夜精品久久| 性欧美xxxx视频在线观看| 香蕉久久国产| 久久精品人人做人人爽电影蜜月| 久久精品国产v日韩v亚洲| 久久精品国产久精国产一老狼 | 日韩午夜三级在线| 亚洲免费观看在线观看| 日韩午夜在线电影| 亚洲一区二区不卡免费| 亚洲欧美激情在线视频| 久久国产精品色婷婷| 久久久久久久999精品视频| 鲁大师影院一区二区三区| 欧美成人资源| 亚洲精品偷拍| 午夜精品电影| 久久亚洲私人国产精品va媚药| 免费观看成人www动漫视频| 欧美精品性视频| 国产精品老女人精品视频| 国产午夜精品久久久| 亚洲国产一区二区三区高清| 一本久道久久综合中文字幕| 亚洲欧美一级二级三级| 久久免费国产精品1| 亚洲国产天堂久久综合网| 99v久久综合狠狠综合久久| 欧美一区二区三区播放老司机| 另类成人小视频在线| 欧美日本亚洲韩国国产| 国产视频一区二区三区在线观看| 亚洲成人自拍视频| 亚洲综合成人在线| 久久久亚洲成人| 亚洲免费黄色| 久久久人成影片一区二区三区| 欧美精选午夜久久久乱码6080| 国产精品色一区二区三区| 亚洲黑丝一区二区| 小黄鸭精品密入口导航| 亚洲第一成人在线| 午夜国产精品影院在线观看| 麻豆精品一区二区综合av| 国产精品色婷婷久久58| 91久久精品美女高潮| 欧美在线观看视频一区二区| 亚洲第一在线综合在线| 午夜精品视频在线| 欧美日韩国产高清视频| 国内精品免费午夜毛片| 亚洲一区二区三区四区五区午夜| 老色鬼精品视频在线观看播放| 99视频在线观看一区三区| 久久男人av资源网站| 国产精品天天摸av网| 夜夜嗨一区二区三区| 麻豆精品在线观看| 亚洲欧美电影在线观看| 欧美日韩黄色一区二区| 亚洲国产欧美一区二区三区同亚洲 | 欧美激情一区二区三区在线视频 | 久久精品国产欧美激情| 999亚洲国产精| 欧美3dxxxxhd| 亚洲电影免费在线观看| 久久精品视频免费| 亚洲午夜视频| 国产精品v亚洲精品v日韩精品| 91久久黄色| 欧美aⅴ一区二区三区视频| 欧美亚洲视频在线看网址| 国产精品一区免费视频| 亚洲欧美另类综合偷拍| 99人久久精品视频最新地址| 欧美日本中文字幕| 亚洲美女精品成人在线视频| 欧美成人日本| 男女激情视频一区| 亚洲国产精品一区制服丝袜| 蜜臀久久99精品久久久久久9| 欧美影院精品一区| 国产一区二区视频在线观看 | 久久综合给合久久狠狠狠97色69| 亚洲欧美日本日韩| 国产拍揄自揄精品视频麻豆| 性做久久久久久久久| 亚洲一区二区在线播放| 国产精品普通话对白| 欧美在线free| 久久精品91久久香蕉加勒比| 狠狠久久亚洲欧美| 媚黑女一区二区| 欧美成人在线影院| 在线一区免费观看| 亚洲无线一线二线三线区别av|