• <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>

            小明思考

            高性能服務器端計算
            posts - 70, comments - 428, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            STL 備忘錄

            Posted on 2006-07-12 11:19 小明 閱讀(5677) 評論(14)  編輯 收藏 引用 所屬分類: C/C++

            [ 不斷補充中]

            1. string.empty() 不是用來清空字符串,而是判斷string是否為空,清空使用string.clear();

            2. string.find等查找的結果要和string::npos比較,而不是和-1比較。(各個平臺可能不同)

            3. 將string轉為char * ,用char * t = (char *)s.c_str() ,而不是 char *t =s.begin() 或者 char *t = &s[0] 或者 char *t =s.data();

            4. 不要用錯string.find ,string::find_first_of ,find和find_first_of有本質區別
            ??? find是查找子串在string出現的位置
            ??? find_first_of是查找第一個匹配目標字符串任何一個字符出現的位置。
            ??? (大多數的時候,需要的是find)

            5. 用swap技巧來移去string(vector)多余的空間
            ?? vector<int> v ;
            ?? ...
            ?? vector<int>(v).swap(v);

            6. 用vector<char>來儲存二進制流

            7. 了解各種儲存bool的優缺點
            vector<bool> 第一,它不是一個真正STL容器,第二,它并不保存bool類(Effective STL 18條)
            deque<bool> 不連續
            vector<char> 太浪費
            bitset 不能動態增長
            boost::dynamic_bitset 不是標準

            8. vector resize()和reserve()分別和size和capacity對應,不要搞錯

            9. vector 的at方法會進行邊界檢查,[]操作符則不會

            10. 使用iterator的時候,自增或者自減,多使用++iter ,--iter的格式。

            11. std::mem_fun/std::mem_fun_ref可以將成員函數用來for_each等方法。
            ?std::vector<Employee> emps;
            ?std::for_each(emps.begin(), emps.end(),
            ??????? std::mem_fun_ref(&Employee::DoStandardRaise);

            ?std::vector<Employee*> emp_ptrs;
            ?std::for_each(emp_ptrs.begin(), emp_ptrs.end(),
            ????????????? std::mem_fun(&Employee::DoStandardRaise));

            12. 如何刪除?
            vector:
            ?vector<int> v;
            ?v.erase(remove(v.begin(), v.end(), 99), v.end());

            list:
            ?list<int> li;
            ?li.remove(99);

            13. 盡量用成員函數代替同名的算法

            14. 循環中刪除map元素的寫法
            typedef map<int,int> mymap;
            typedef map<int,int>::iterator myiter;
            mymap m;??? m[1] = 2;??? m[2] = -1;??? m[3] = 3;??? m[4] = 0;??? m[5] = -5;??? m[6] = 1;
            myiter iter = m.begin();

            ??? while(iter!=m.end())??? {
            ??????? if(iter->second<0)???
            ??????????? m.erase(iter++);
            ??????? else????
            ??????????? ++iter;
            ??? }

            15. 從ifstream讀出一行到string,使用std::getline(ifstream的成員函數getline做不到)

            16.警惕string的引用記數技術實現帶來的潛在問題

            string greet("Hello, world");
            string hi(greet);
            char *ptr = (char *)hi.c_str();
            ptr[0] = 'h';
            兩個字符串都被修改。

            在多線程之間引用多個有關系的string,可能導致引用計數失效,造成多次刪除,或者memory leak.
            保險的做法是:
            string s1("hello") ; string s2 (s1.c_str()); //force copy
            ?

            17.自定義類放入stl容器中,應注意實現安全的copy ctor和assign operator.尤其是含有指針的class,避免多次刪除

            18.避免iterator失效,不提取無效的iterator
            比如:
            vector<int> iv;
            vector<int>::iterator end = iv .end();
            for(int i=0;i<10;++i)
            ??? iv.insert(end,i);
            會crash ,因為end指針,隨著insert后可能失效
            改為:
            vector<int> iv;
            for(int i=0;i<10;++i)
            ??? iv.insert(iv.end(),i);
            或者:
            vector<int> iv;
            for(int i=0;i<10;++i)
            ??? iv.push_back(i); //prefer


            19. 不要把std::auto_ptr用于數組指針
            auto_ptr<int> p(new int[10]); //maybe cause memory leak

            20. 不要直接修改set,map的鍵值,如果要修改,先erase,再insert.

            21. 多線程下,幾個線程如果共同操作一個容器,安全性(鎖)應該由用戶自己來實現,stl不保證這一點
            例如,一個多線程安全的deque
            template<typename T,class ThreadModel=MultiThread>
            class CDequePool:private ThreadModel {
            ??private:
            ???std::deque<T> m_clDeque;?
            //.....???
            ??public:
            ???bool PutData(const T &data)
            ???{
            ????Lock();
            ????m_clDeque.push_front(data);
            ????Unlock();
            ????return true;
            ???}
            //....
            }

            Feedback

            # re: STL 備忘錄  回復  更多評論   

            2006-07-12 11:34 by 周星星
            up一下

            # re: STL 備忘錄  回復  更多評論   

            2006-07-12 15:47 by Arcrest
            呵呵,都是Effective STL里面的條目啊
            那個12點有點詭異,也容易忘記,不過知道remove的原理就容易記住了

            # re: STL 備忘錄  回復  更多評論   

            2006-07-12 16:10 by 3×7=51
            第7條我表示反對,即使它是Meyers說的。我更愿意把它改為"了解vector<bool>的特殊之處"

            # re: STL 備忘錄  回復  更多評論   

            2006-07-12 16:38 by 小明
            Meyers說到:
            做為一個STL容器,vector<bool>有兩個問題.第一,它不是一個真正STL容器,第二,它并不保存bool類型.

            vector<bool> v;
            bool *pb = &v[0]; // initialize a bool* with the address of
            // what vector<bool>::operator[] returns

            但是它不能編譯.不能的原因是vector<bool>是一個偽容器(pseudo-container),它并不保存真正的bool,而是打包bool以節省空間.

            # re: STL 備忘錄  回復  更多評論   

            2006-07-12 17:22 by 3×7=51
            Meyers說的俺知道,可是vector<bool>自然還有它的用途,我們不能因為它不能用在A處,所以就也不把它用于B處。

            # re: STL 備忘錄  回復  更多評論   

            2006-07-12 17:29 by 小明
            因為Meyers說過,所以我就不敢用vector<bool>了,我想bitset總是可以替代vector<bool>了。Meyers也來提到了用deque<bool>來代替
            所以不用vector<bool>是一種保險/安全的做法。
            安全/穩妥第一。

            # re: STL 備忘錄  回復  更多評論   

            2006-07-12 17:34 by 3×7=51
            bitset試無法替代vector<bool>因為它無法動態增長。而如果使用deque<bool>則一樣無法保證begin到end之間空間的連續。所以似乎也沒多大的用處。而bitset跟vector<bool>一樣是用位域來表示bool的。

            # re: STL 備忘錄  回復  更多評論   

            2006-07-12 17:42 by 小明
            恩,總結一下
            vector<bool> Meyers不讓用
            deque<bool> 不連續
            vector<char> 太浪費
            bitset 不能動態增長
            boost::dynamic_bitset 不是標準

            # re: STL 備忘錄  回復  更多評論   

            2006-07-12 18:21 by 3×7=51
            不,我不覺得vector<bool>不可以使用,相反我們可以大膽地使用,反正如果象Meyers說的那種誤用了會報錯(是否會報錯我不確定,是看你們說的,反正我從沒那樣用過)。

            # re: STL 備忘錄  回復  更多評論   

            2006-07-14 11:25 by darkay
            3. 將string轉為char * ,用char * t = (char *)s.c_str() 或者 char *t = &s[0] ,而不是 char *t =s.begin();

            == 不應該用 &s[0],因為不能假設sting的內部實現的內存是連續的,但是 c_str()返回的則規范要求是連續的。

            # re: STL 備忘錄  回復  更多評論   

            2006-07-14 13:38 by 小明
            @darkay
            ok,我修改第3條,謝謝

            @3×7=51
            我修改了第7條,謝謝

            # re: STL 備忘錄  回復  更多評論   

            2006-10-14 21:16 by 羅賓李
            不錯。
            用swap技巧應該是
            vector<int>().swap(v);

            # re: STL 備忘錄  回復  更多評論   

            2006-10-16 10:03 by 小明
            @羅賓李

            表達式vector<int>(v)創建一個臨時的vector,它是v的拷貝:vector的拷貝構造函數完成這一工作.但是vector的拷貝構造函數僅申請適合需要的空間來復制.因此臨時vector不包含多余空位.然后交換臨時對象和v的數據,結果臨時對象包含著過多的空間,這些空間曾經是v的,最后,臨時對象銷毀,并釋放空間.Yes,收縮至合適.


            所以vector<int>(v).swap(v); 是正確的

            # re: STL 備忘錄  回復  更多評論   

            2007-12-17 17:05 by 秦歌
            頂!
            大香网伊人久久综合网2020| 亚洲AV无码久久| 久久亚洲国产精品五月天婷| 久久人人爽人人澡人人高潮AV| 亚洲?V乱码久久精品蜜桃 | A级毛片无码久久精品免费| 国产福利电影一区二区三区,免费久久久久久久精 | 精品久久久久久中文字幕大豆网| 久久人爽人人爽人人片AV| 爱做久久久久久| 亚洲精品白浆高清久久久久久 | 88久久精品无码一区二区毛片| 久久久久久一区国产精品| 看久久久久久a级毛片| 亚洲婷婷国产精品电影人久久 | 久久久久人妻一区精品色| 久久亚洲国产成人影院网站| 久久精品水蜜桃av综合天堂| 亚洲国产精品无码久久青草| 久久本道伊人久久| 99久久精品免费看国产一区二区三区 | 久久精品无码av| 国产精品99久久99久久久| 99久久99这里只有免费的精品| 成人综合久久精品色婷婷 | 久久午夜福利无码1000合集| 国内精品久久久久久麻豆| 99国产欧美精品久久久蜜芽| 亚洲AV无码1区2区久久| 7777精品久久久大香线蕉| 色天使久久综合网天天| 久久本道综合久久伊人| 伊人久久大香线蕉影院95| 欧美精品一区二区精品久久| 久久国产亚洲精品无码| 2021久久国自产拍精品| 欧美牲交A欧牲交aⅴ久久| 日日躁夜夜躁狠狠久久AV| 午夜欧美精品久久久久久久| 午夜精品久久久久久毛片| 久久久久久无码Av成人影院|