最近有閑,在工作之余重讀了《effective STL》一書,并通過 twitter 記了一下筆記,今天整理收集到這里。
twitter 真的非常適合記讀書筆記,哈哈,以后要好好地發揚。另,我的手機還是很老的 UIQ 3.0 的索愛手機,有沒有達人推薦一些上推的應用程序?謝謝。
====================================
#estl 第50條:熟悉與STL相關的web站點。三個:www.sgi.com/tech/stl、www.stlport.org 和 www.boost.org。
#estl 第49條:學會分析與STL相關的編譯器診斷信息。嗯,第一招是替換大法,然后介紹了一下與容器、插入迭代器、綁定器、輸出迭代器或算法相關的錯誤大概有什么套路看。
#estl 第48條:總是包含(#include)正確 的頭文件。因為C++標準沒有規定頭文件的互相包含關系,所以不同的STL實現有所不同。要記住容器基本上聲明在同名文件中,算法是algo..和 num..,迭代器在iterator中,函數子和配接器在functional中。
#estl 第47條:避免產生“直寫型”(write-only)的代碼。即所謂容易編寫,但難以閱讀和理解的代碼,比如一行調用函數12次,其中 10 個是互不相同的。
#estl 第46條:考慮使用函數對象而不是函數作為STL算法的參數。嗯,因為函數對象更容易讓編譯器樂于內聯,所以速度會快一些。從代碼被編譯器接受的程度而言,它們更加穩定可靠。
#estl 第45條:正確區分count、find、binary_search、lower_bound、upper_bound和equal_range。嗯,這與傳入的區間是否已經排序有關,與你的目的有關,與容器有關,總之復雜,要自己去看這一小節兩次。
googollee 我一直認為這個應該由重載來完成 RT @laiyonghao: #estl 第44條:容器的成員函數優先于同名的算法。原因:速度更快,且與容器結合得更加緊密,更能夠與容器的行為保持一致。
#estl 第44條:容器的成員函數優先于同名的算法。原因:速度更快,且與容器結合得更加緊密,更能夠與容器的行為保持一致。
#estl 第43條:算法調用優先于手寫的循環。三個理由:效率更高,更不容易出錯,和更好的可維護性。
#estl 第42條:確保less<T>與operator<T>具有相同的語義。真理總是如此平淡……還能說啥呢?
#estl 第41條:理解ptr_fun、mem_fun和mem_fun_ref的來由??龋肫甬斈昀斫?.* 和 ->* 的時候多么地頭痛……
#estl 第40條:若一個類是函數子,則應使它可配接。因為 STL 的函數配接器要求一些特殊的類型定義,argument_type,result_type...之類。編寫函數子從unary_function或 binary_function繼承是一個不錯的方案。
#estl 第39條:確保判別式是“純函數”。純函數即返回值僅僅依賴于其參數的函數。估計在這條陰溝里翻過船的人不少,哈哈哈。
#estl 第38條:遵循按值傳遞的原則來設計函數子類。換句話說就是讓它們小巧,而且單態。這個條款的意義在于為贅重而且多態的函數子帶來的問題提出一個解決方案,pimpl 慣用法。
#estl 第37條:使用accumulate或者for_each進行區間統計,前者的代碼更明了一些,重要的是它們接受的函數子要求不同。
#estl 第36條:理解copy_if算法的正確實現。文中給出了一個正確實現,注意點是不能要求使用的函數子是可配接的,STL 算法都這樣。
#estl 第35條:通過mismatch或lexicographical_compare實現簡單的忽略大小寫的字符串比較。
#estl 第34條:了解哪此算法要求使用排序的區間作為參數。嗯,STL 算法有不少是要排序的區間的,如果實參并非如此,輕則性能下降,重則邏輯錯誤,不可不察。
#estl 第33條:對包含指針的容器使用remove這一類算法時要特別小心。作為cpp程序員,一定要時刻警惕資源泄漏。boost::shared_ptr是一個好選擇。
#estl 第32條:如果確實需要刪除元素,則需要在remove這一類算法之后調用erase。嗯,講的就是erase-remove慣用法的由來,另外在講了一次不同容器刪除元素的方法是不同的。
#estl 第31條:了解各種與排序有關的選擇。簡言之,介紹了partition/stable_partition/nth_element /partial_sort/sort/stable_sort的用法和適用場合。
吼吼,到這里,書就看了一半了。接下來是重頭戲:算法。 #estl 第30條:確保目標區間足夠大。特別是做覆蓋的時候,一定要注意,可以先用resize撐大。插入時用back_inserter、front_...、 inserter和ostream_iterator。
#estl 第29條:對于逐個字符的輸入請考慮使用istreambuf_iterator。先說了一下istream_iterator會跳過空白符的問題,然后引入...buf...,后者的性能也會更好,嗯,例子里的string使用了區間構造函數,又一個推薦的慣用法。
#estl 第28條:正確理解由reverse_itrator的base()成員函數所產生的iterator用法。簡言之就是base()返回的迭代器有偏移,插入和刪除操作的時候要注意。再介紹了一個v.erase((++ri).base())慣用法。
#estl 第27條:使用distance和advance將容器的const_iterator轉換成iterator。其實這是前一條的延伸,講述了相應的轉換方法和要注意的地方,比如顯式指定distance的類型參數為const_...,以避免編譯器推斷。
周末在家繼續看了一點點書,補推上來。 #estl 第26條:iterator優先于const_iterator、reverse_...以及const_reverse...。因為 insert/erase等函數需要,以及彼此間的比較,還有就是iterator更能靈活轉換。
=============== 一半的分割線 ==================
#estl 第25條:熟悉非標準的哈希容器。嗯,這些玩意兒是非標準的,C++0x 出來以后就會有標準了……
RT @googollee: 用vector的好處是內存布局可控,可直接導給c api。應該是vector性能不行了才用關聯容器 RT @laiyonghao #estl 第23條:考慮用排序的vector替代關聯容器。……//維護一個sorted_vector代價挺大的。
#estl 第24條:當效率至關重要時,請在map::operator[]與map::insert之間謹慎做出選擇。簡言之,增加時使用insert,更新時使用[]。
#estl 第23條:考慮用排序的vector替代關聯容器。額,我覺得除非證明了關聯容器性能不行了,不然不應該考慮。map 不行了用 hashmap。
#estl 第22條:切勿直接修改set或multiset中的鍵。關鍵是要記住如果直接修改了,那么要保證該容器仍然是排序的。對python之類的語言其實也是如此。
#estl 第21條:總是讓比較函數在等值情況下返回false。聽起來像廢話?嗯,重要的是要記得 !(a<b) 的意思是 a>=b,切記要把前者寫成 b<a 形式。 回復 回推
#estl 第20條:為包含指針的關聯容器指定比較類型。這條已經約定成俗了,沒什么好說的。
#estl 第19條:理解相等(equality)和等價(equivalence)的區別。相等,以 operator== 為基礎,等價,以 operator< 為基礎,當 !(a<b)&&!(b<a) 時兩者等價。
#estl 讀完第2章,再感嘆一下溫故知新。另外 twitter 真是做讀書筆記的好工具。
#estl 第18條:避免使用vector<bool>。這條也是金規玉律了,無需多言。
#estl 第17條:使用“swap技巧”去除多余的容量。這條太常用了,沒啥好說的。
#estl 第16條:了解如何把 vector和string數據傳給舊的API。嗯,再一次覺得&v[0]實在太惡心了。因為只有vector才保證和數組有同樣的內存布局,所以如果要把map之類的容器內容傳給C-API,可能需要vector中轉一下。
#estl 第15條:注意string實現的多樣性。談到了四個不同的實現,并分析了他們占用的內存大小,引用和共享能力。非常有趣。
#estl 第14條:使用reserve來避免不必要的重新分配。先分析了vector/string的內存策略和相關的方法,然后談到reserve慣用法。
#estl 第13條:vector和string優先于動態分配的數組。主要因為它們的內存管理和各種嵌套類型定義方便編程,另外討論到基于引用計數的string 可能在多線程環境中損失性能。
重看 #estl 已經看完第一章了,我不得不說 C++ 的書是會中毒的,我現在變得有很強的欲望去重看 ecpp 和 mecpp 了……我好不容易通過寫py三年修來的金身馬上要破了……
#estl 第12條:切勿對STL容器的線程安全性有不切實際的依賴。只能期望(不可依賴哦)多線程讀是安全的,多個線程對不同的容器做寫入操作是安全的。
#estl 又讀了一遍第10條。第11條:理解自定義分配子的合理用法。
#estl 第10條:了解分配子(allocator)的約定和限制。果然溫故知新,這一條耗了我好幾個編譯代碼的時間……可能仍然需要再重讀幾遍,鵝米豆腐……
#estl 第8條:切勿創建包含auto_ptr的容器對象;第9條:慎重選擇刪除元素的方法。關鍵點:auto_ptr在拷貝時轉移所有權;序列容器和關聯容器的刪除方法不一樣,list尤其特別。
RT @googollee: 第7條看情況吧,如果容器里的東西在容器銷毀后還需要繼續存在的話就不能delete。ecpp是embedded cpp么? RT @laiyonghao: #ecpp 第7條…… // 我用錯tag了,effective stl,以后改 #estl
#ecpp 第7條:如果容器中包含了通過new操作創建的指針,切記在容器對象析構前將指針delete掉;第8條:切勿創建包含auto_ptr的容器對象。
#ecpp 第6條:當心C++編譯器最煩人的分析機制。意思大概是在函數調用時避免使用匿名對象作實參,以消除對編譯器的二義性。
#ecpp 第5條:區間成員函數優先于與之對應的單元素成員函數。區間成員函數寫起來更容易,更能清楚地表達你的意圖,而且它們表現出了更高的效率。
#ecpp 第3條:確保容器中的對象拷貝正確而高效;第4條:調用 empty 而不是檢查 size() 是否為 0。
重讀《Effective STL 中文版》。第1條:慎重選擇容器類型;第2條:不要試圖編寫獨立于容器類型的代碼。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
