讀書筆記之 Effective STL

2022-05-13 15:00:59 字數 3068 閱讀 2329

條款3:使容器裡物件的拷貝操作輕量而正確

stl中採用的都是拷貝物件的方式

如果所有這些使stl的拷貝機制聽起來很瘋狂,就請重新想想。是,stl進行了大量拷貝,但它通常設計為避免不必要的物件拷貝,實際上,它也被實現為避免不必要的物件拷貝。和c和c++內建容器的行為做個對比,下面的陣列:

widget w[maxnumwidgets];// 建立乙個大小為maxnumwidgets的widgets陣列

// 預設構造每個元素

即使我們一般只使用其中的一些或者我們立刻使用從某個地方獲取(比如,乙個檔案)的值覆蓋每個預設構造的值,這也得構造maxnumwidgets個widget物件。使用stl來代替陣列,你可以使用乙個可以在需要的時候增長的vector:

vectorvw;// 建立乙個0個widget物件的vector

// 需要的時候可以擴充套件

我們也可以建立乙個可以足夠包含maxnumwidgets個widget的空vector,但沒有構造widget:

vectorvw;

vw.reserve(maxnumwidgets);// reserve的詳細資訊請參見條款14

和陣列對比,stl容器更文明。它們只建立(通過拷貝)你需要的個數的物件,而且它們只在你指定的時候做。是的,我們需要知道stl容器使用了拷貝,但是別忘了乙個事實:比起陣列它們仍然是乙個進步。

條款5:盡量使用區間成員函式代替它們的單元素兄弟

條款4:用empty來代替檢查size()是否為0

條款6:警惕c++最令人惱怒的解析

c++裡的一條通用規則——幾乎任何東西都可能被分析成函式宣告。

引數為函式指標的三種宣告形式:

int g(double (*pf)());//最一般的方式

int g(double pf());// 同上;pf其實是乙個指標

int g(double ());// 同上;引數名省略

所以對於下面的宣告:

istdata(istream_iterator(datafile), istream_iterator());
這宣告了乙個函式data,它的返回型別是list。這個函式data帶有兩個引數:

●第乙個引數叫做datafile。它的型別是istream_iterator。datafile左右的括號是多餘的而且被忽略。

●第二個引數沒有名字。它的型別是指向乙個沒有引數而且返回istream_iterator的函式的指標。

還有對於這條規則最常見的乙個例子:

class widget ; // 假設widget有預設建構函式

widget w();// 這是乙個函式宣告,並沒有呼叫建構函式

條款8:永不建立auto_ptr的容器

條款18:避免使用vector

條款25:熟悉非標準雜湊容器

sgi設計的乙個值得注意的方面是使用equal_to作為預設比較函式。這違背標準關聯容器的約定——預設比較函式是less。這個設計結果不僅僅表示簡單地改變預設比較函式。sgi的雜湊容器確定在乙個雜湊容器中的兩個物件是否有相同的值是通過相等測試,而不是等價(參見條款19)。對於雜湊容器來說,這不是乙個不合理的決定,因為雜湊關聯容器,不像它們在標準中的(通常基於樹)兄弟,不需要保持有序。

dinkumware設計的雜湊容器採取一些不同的策略。它仍然允許你指定物件型別、雜湊函式型別、比較函式型別和分配器型別,但是它把預設的雜湊和比較函式移進乙個單獨的類似特性的叫做hash_compare的類,而且它把hash_compare作為容器模板的hashinginfo實參的預設值。(如果你不熟悉「特性」類的概念,開啟一本好的stl參考,比如josuttis的《c++ standard library》[3]並學習char_traits和iterator_traits模板的動機和實現。)

在後端,sgi和dinkumware的實現方法非常不同。sgi利用常用的乙個元素的單鏈表的指標陣列(桶)組成的開放雜湊法。dinkumware也利用了開放雜湊法,但是它的設計是基於一種新穎的資料結構——由迭代器(本

質是桶)的陣列組成的元素雙向鍊錶,迭代器的相鄰對表示在每個桶裡元素的範圍。(細節可以參考plauger相關主題的專欄,《hash tables》[16]。)

條款43:盡量用演算法呼叫代替手寫迴圈

有三個理由:

公平的說,stl的實現者知道begin和end(以及類似的函式,比如size)用得很頻繁,所以他們盡可能把它們實現得最高效。幾乎肯定會inline它們,並努力編碼使得絕大部分編譯器都可以通過將計算結果提到迴圈外(譯註:頻度優化的一種)來避免重複計算。然而,經驗表明,這樣的實現不是總可以成功的,而且當不成功時,對重複計算的避免足以讓演算法比手寫的迴圈具有效能優勢。

條款44:盡量用成員函式代替同名的演算法

有些容器擁有和stl演算法同名的成員函式。關聯容器提供了count、find、lower_bound、upper_bound和equal_range,而list提供了remove、remove_if、unique、sort、merge和reverse。大多數情況下,你應該用成員函式代替演算法。這樣做有兩個理由。首先,成員函式更快。其次,比起演算法來,它們與容器結合得更好(尤其是關聯容器)。那是因為同名的演算法和成員函式通常並不是是一樣的。

效率不是find成員函式和find演算法間的唯一差別。正如條款19所解釋的,stl演算法判斷兩個物件是否相同的方法是檢查的是它們是否相等,而關聯容器是用等價來測試它們的「同一性」。 因此,find演算法搜尋用的是

對於標準的關聯容器,選擇成員函式而不是同名的演算法有幾個好處。首先,你得到的是對數時間而不是線性時間的效能。其次,你判斷兩個元素「相同」使用的是等價,這是關聯容器的預設定義。第三,當操縱map和multimap時,你可以自動地只處理key值而不是(key, value)對。這三點給了優先使用成員函式完美的鐵甲。

讀書筆記 之五

筆者的話 接觸硬體較少,很多術語都是字面翻譯,讀者請見諒.我盡量帶上英文原詞,避免歧義.2.2 磁碟驅動器元件 磁碟驅動器使用快速移動的臂來在大唱片一樣的覆蓋著小磁粒的碟片上讀寫資料的.資料從磁碟片上通過r w頭傳輸到計算機中.多個碟片,讀寫頭和控制器被組合在一起,通常這被稱為是硬碟驅動器 hard...

讀書筆記之TCP UDP

網際網路,更一般的是tcp ip網路為應用程式提供兩個運輸層協議,即udp和tcp。當乙個軟體開發者為英特網建立乙個新的應用時,首先要做出的決定就是,選擇使用tcp協議還是udp協議。每個協議為呼叫他們的應用程式提供了不同的服務集合。tcp服務模型包括面向連線服務和可靠資料傳輸服務。當某個應用程式呼...

讀書筆記之C delegate

c 的使用主要在 需要將乙個方法當做引數傳遞到另乙個方法時。比如啟動乙個執行緒執行任務,而這個執行緒要執行的方法可以通過 傳遞過來。包括乙個方法或者多個方法的位址和c 的函式指標很相似,但它是型別安全的。1.宣告 delegate void intmethodinvoker int x 這個 可以引...