這里是一組在你學(xué)習(xí)C++的過(guò)程中或許應(yīng)該考慮的“規(guī)則”。隨著你變得更加熟練,你將能
把它轉(zhuǎn)化為某種更適合你的那類(lèi)應(yīng)用系統(tǒng)或者你自己的程序設(shè)計(jì)風(fēng)格的東西。它們有意被
寫(xiě)得很簡(jiǎn)單,因此都缺乏細(xì)節(jié)。請(qǐng)不要太拘泥于它們的字面意義。要寫(xiě)出一個(gè)好程序需要
智慧、品味和耐性。你不會(huì)第一次就能把它搞好的。試驗(yàn)!
[1]在編程序時(shí),你是在為你針對(duì)某個(gè)問(wèn)題的解決方案中的思想建立起一種具體表示。讓程
序的結(jié)構(gòu)盡可能地直接反映這些思想:
[a] 如果你能把“它”看成一個(gè)獨(dú)立的概念,就把它做成一個(gè)類(lèi)。
[b] 如果你能把“它”看成一個(gè)獨(dú)立的實(shí)體,就把它做成某個(gè)類(lèi)的一個(gè)對(duì)象。
[c] 如果兩個(gè)類(lèi)有共同的界面,將此界面做成一個(gè)抽象類(lèi)。
[d] 如果兩個(gè)類(lèi)的實(shí)現(xiàn)有某些顯著的共同東西,將這些共性做成一個(gè)基類(lèi)。
[e] 如果一個(gè)類(lèi)是一種對(duì)象的容器,將它做成一個(gè)模板。
[f] 如果一個(gè)函數(shù)實(shí)現(xiàn)對(duì)某容器的一個(gè)算法,將它實(shí)現(xiàn)為對(duì)一族容器可用的模板函數(shù)。
[g] 如果一組類(lèi)、模板等互相之間有邏輯聯(lián)系,將它們放進(jìn)一個(gè)名字空間里。
[2]在你定義一個(gè)并不是實(shí)現(xiàn)某個(gè)像矩陣或復(fù)數(shù)這樣的數(shù)學(xué)對(duì)象的類(lèi)時(shí),或者定義一個(gè)低層
的類(lèi)型如鏈接表的時(shí)候:
[a] 不要使用全局?jǐn)?shù)據(jù)(使用成員)。
[b] 不要使用全局函數(shù)。
[c] 不要使用公用數(shù)據(jù)成員。
[d] 不要使用友元,除非為了避免[a]或[c]。
[e] 不要在一個(gè)類(lèi)里面放“類(lèi)型域”;采用虛函數(shù)。
[f] 不要使用在線(xiàn)函數(shù),除非作為效果顯著的優(yōu)化。
更特殊或更詳盡的實(shí)用規(guī)則可以在每章最后的“忠告”一節(jié)里找到。請(qǐng)記住,這些忠告只
是粗略的實(shí)用規(guī)則,而不是萬(wàn)古不變的定律。它們只應(yīng)使用在“合理的地方”。從來(lái)就沒(méi)
有任何東西能夠替代智慧、經(jīng)驗(yàn)、常識(shí)和好的鑒賞力。
我發(fā)現(xiàn)具有“絕不要做這個(gè)”形式的規(guī)則不大有幫助。因此,大部分忠告被寫(xiě)成應(yīng)該做什
么的建議,而否定性的建議也傾向于不采用絕對(duì)禁止的短語(yǔ)。據(jù)我所知,沒(méi)有任何一種主
要的C++特征沒(méi)有被良好地使用過(guò)。在有關(guān)“忠告”的節(jié)里不包括解釋?zhuān)喾?,每條忠告都
引用了本書(shū)中某些適當(dāng)?shù)恼鹿?jié)。在給出否定性的忠告時(shí),對(duì)應(yīng)章節(jié)里通常都提供了有關(guān)其
他替代方式的建議。
第2章忠告
[1] 不用害怕,一切都會(huì)隨著時(shí)間的推移而逐漸明朗起來(lái);2.1節(jié)。
[2] 你并不需要在知道了C++的所有細(xì)節(jié)之后才能寫(xiě)出好的C++程序;1.7節(jié)。
[3] 請(qǐng)?zhí)貏e關(guān)注程序設(shè)計(jì)技術(shù),而不是各種語(yǔ)言特征;2.1節(jié)。
第3章忠告
[1] 不要像重新發(fā)明車(chē)輪那樣企圖做每件事;去使用庫(kù)。
[2] 不要相信奇跡;要理解你的庫(kù)能做什么,它們?nèi)绾巫?,它們做時(shí)需要多大的代價(jià)。
[3] 當(dāng)你遇到一個(gè)選擇時(shí),應(yīng)該優(yōu)先選擇標(biāo)準(zhǔn)庫(kù)而不是其他的庫(kù)。
[4] 不要認(rèn)為標(biāo)準(zhǔn)庫(kù)對(duì)于任何事情都是最理想的。
[5] 切記#include你所用到的功能的頭文件;3.3節(jié)。
[6] 記住,標(biāo)準(zhǔn)庫(kù)的功能定義在名字空間std之中;3.3節(jié)。
[7] 請(qǐng)用string,而不是char*;3.5節(jié)、3.6節(jié)。
[8] 如果懷疑,就用一個(gè)檢查區(qū)間范圍的向量(例如Vec);3.7.2節(jié)。
[9] vector、list和map 都比T[ ] 好;3.7.1節(jié)、3.7.3節(jié)、3.7.4節(jié)。
[10] 如要向一個(gè)容器中添加一個(gè)元素,用push_back()或back_inserter();3.7.3節(jié)、3.
8節(jié)。
[11] 采用對(duì)vector的push_back(),而不是對(duì)數(shù)組的realloc();3.8節(jié)。
[12] 在main()中捕捉公共的異常;3.7.2節(jié)。
第4章忠告
[1] 保持較小的作用域;4.9.4節(jié)。
[2] 不要在一個(gè)作用域和它外圍的作用域里采用同樣的名字;4.9.4節(jié)。
[3] 在一個(gè)聲明中(只)聲明一個(gè)名字;4.9.2節(jié)。
[4] 讓常用的和局部的名字比較短,讓不常用的和全局的名字比較長(zhǎng);4.9.3節(jié)。
[5] 避免看起來(lái)類(lèi)似的名字;4.9.3節(jié)。
[6] 維持某種統(tǒng)一的命名風(fēng)格;4.9.3節(jié)。
[7] 仔細(xì)選擇名字,反映其意義而不是反映實(shí)現(xiàn)方式;4.9.3節(jié);
[8] 如果所用的內(nèi)部類(lèi)型表示某種可能變化的值,請(qǐng)用typedef為它定義一個(gè)有意義的名字
;4.9.7節(jié)。
[9] 用typedef為類(lèi)型定義同義詞,用枚舉或類(lèi)去定義新類(lèi)型;4.9.7節(jié)。
[10] 切記每個(gè)聲明中都必須描述一個(gè)類(lèi)型(沒(méi)有“隱式的int”);4.9.1節(jié)。
[11] 避免有關(guān)字符數(shù)值的不必要假設(shè);4.3.1節(jié)、C.6.2.1節(jié)。
[12] 避免有關(guān)整數(shù)大小的不必要假設(shè);4.6節(jié)。
[13] 避免有關(guān)浮點(diǎn)類(lèi)型表示范圍的不必要假設(shè);4.6節(jié)。
[14] 優(yōu)先使用普通的int而不是short int或者long int;4.6節(jié)。
[15] 優(yōu)先使用double而不是float或者long double;4.5節(jié)。
[16] 優(yōu)先使用普通的char而不是signed char或者unsigned char;C.3.4節(jié)。
[17] 避免做出有關(guān)對(duì)象大小的不必要假設(shè); 4.6節(jié)。
[18] 避免無(wú)符號(hào)算術(shù);4.4節(jié)。
[19] 應(yīng)該帶著疑問(wèn)去看待從signed到unsigned,或者從unsigned到signed的轉(zhuǎn)換;C.6.2
.6節(jié)。
[20] 應(yīng)該帶著疑問(wèn)去看待從浮點(diǎn)到整數(shù)的轉(zhuǎn)換; C.6.2.6節(jié)。
[21] 應(yīng)該帶著疑問(wèn)去看待向較小類(lèi)型的轉(zhuǎn)換,如將int轉(zhuǎn)換到char;C.6.2.6節(jié)。
第5章忠告
[1] 避免非平凡的指針?biāo)阈g(shù);5.3節(jié)。
[2] 當(dāng)心,不要超出數(shù)組的界線(xiàn)去寫(xiě);5.3.1節(jié)。
[3] 盡量使用0而不是NULL;5.1.1節(jié)。
[4] 盡量使用vector和valarray而不是內(nèi)部(C風(fēng)格)的數(shù)組;5.3.1節(jié)。
[5] 盡量使用string而不是以0結(jié)尾的char數(shù)組;5.3節(jié)。
[6] 盡量少用普通的引用參數(shù);5.5節(jié)。
[7] 避免void*,除了在某些低級(jí)代碼里;5.6節(jié)。
[8] 避免在代碼中使用非平凡的文字量(“神秘的數(shù)”)。相反,應(yīng)該定義和使用各種符
號(hào)常量。4.8節(jié)、5.4節(jié)。
第6章忠告
[1] 應(yīng)盡可能使用標(biāo)準(zhǔn)庫(kù),而不是其他的庫(kù)和“手工打造的代碼”;6.1.8節(jié)。
[2] 避免過(guò)于復(fù)雜的表達(dá)式;6.2.3節(jié)。
[3] 如果對(duì)運(yùn)算符的優(yōu)先級(jí)有疑問(wèn),加括號(hào);6.2.3節(jié)。
[4] 避免顯式類(lèi)型轉(zhuǎn)換(強(qiáng)制);6.2.7節(jié)。
[5] 若必須做顯式類(lèi)型轉(zhuǎn)換,提倡使用特殊強(qiáng)制運(yùn)算符,而不是C風(fēng)格的強(qiáng)制;6.2.7節(jié)。
[6] 只對(duì)定義良好的構(gòu)造使用T(e)記法;6.2.8節(jié)。
[7] 避免帶有無(wú)定義求值順序的表達(dá)式; 6.2.2節(jié)。
[8] 避免goto;6.3.4節(jié)。
[9] 避免do語(yǔ)句;6.3.3節(jié)。
[10] 在你已經(jīng)有了去初始化某個(gè)變量的值之前,不要去聲明它;6.3.1節(jié)、6.3.2.1節(jié)、6
.3.3.1節(jié)。
[11] 使注釋簡(jiǎn)潔、清晰、有意義;6.4節(jié)。
[12] 保持一致的縮進(jìn)編排風(fēng)格;6.4節(jié)。
[13] 傾向于去定義一個(gè)成員函數(shù)operator new()(15.6節(jié))去取代全局的operator new(
);6.2.6.2節(jié)。
[14] 在讀輸入的時(shí)候,總應(yīng)考慮病態(tài)形式的輸入;6.1.3節(jié)。
第7章忠告
[1] 質(zhì)疑那些非const的引用參數(shù);如果你想要一個(gè)函數(shù)去修改其參數(shù),請(qǐng)使用指針或者返
回值;5.5節(jié)。
[2] 當(dāng)你需要盡可能減少參數(shù)復(fù)制時(shí),應(yīng)該使用const引用參數(shù);5.5節(jié)。
[3] 廣泛而一致地使用const;7.2節(jié)。
[4] 避免宏;7.8節(jié)。
[5] 避免不確定數(shù)目的參數(shù);7.6節(jié)。
[6] 不要返回局部變量的指針或者引用;7.3節(jié)。
[7] 當(dāng)一些函數(shù)對(duì)不同的類(lèi)型執(zhí)行概念上相同的工作時(shí),請(qǐng)使用重載;7.4節(jié)。
[8] 在各種整數(shù)上重載時(shí),通過(guò)提供函數(shù)去消除常見(jiàn)的歧義性;7.4.3節(jié)。
[9] 在考慮使用指向函數(shù)的指針時(shí),請(qǐng)考慮虛函數(shù)(2.5.5節(jié))或模板(2.7.2節(jié))是不是
一種更好的選擇;7.7節(jié)。
[10] 如果你必須使用宏,請(qǐng)使用帶有許多大寫(xiě)字母的丑陋的名字;7.8節(jié)。
第8章忠告
[1] 用名字空間表示邏輯結(jié)構(gòu);8.2節(jié)。
[2] 將每個(gè)非局部的名字放入某個(gè)名字空間里,除了main()之外;8.2節(jié)。
[3] 名字空間的設(shè)計(jì)應(yīng)該讓你能很方便地使用它,而又不會(huì)意外地訪(fǎng)問(wèn)了其他的無(wú)關(guān)名字
空間;8.2.4節(jié)。
[4] 避免對(duì)名字空間使用很短的名字;8.2.7節(jié)。
[5] 如果需要,通過(guò)名字空間別名去緩和長(zhǎng)名字空間名的影響; 8.2.7節(jié)。
[6] 避免給你的名字空間的用戶(hù)添加太大的記法負(fù)擔(dān);8.2.2節(jié)、8.2.3節(jié)。
[7] 在定義名字空間的成員時(shí)使用namespace::member的形式;8.2.8節(jié)。
[8] 只在轉(zhuǎn)換時(shí),或者在局部作用域里,才用using namespace;8.2.9節(jié)。
[9] 利用異常去松弛“錯(cuò)誤”處理代碼和正常處理代碼之間的聯(lián)系;8.3.3節(jié)。
[10] 采用用戶(hù)定義類(lèi)型作為異常,不用內(nèi)部類(lèi)型;8.3.2節(jié)。
[11] 當(dāng)局部控制結(jié)構(gòu)足以應(yīng)付問(wèn)題時(shí),不要用異常;8.3.3.1節(jié)。
第9章忠告
[1] 利用頭文件去表示界面和強(qiáng)調(diào)邏輯結(jié)構(gòu);9.1節(jié)、9.3.2節(jié)。
[2] 用#include將頭文件包含到實(shí)現(xiàn)有關(guān)功能的源文件里;9.3.1節(jié)。
[3] 不要在不同編譯單位里定義具有同樣名字,意義類(lèi)似但又不同的全局實(shí)體;9.2節(jié)。
[4] 避免在頭文件里定義非inline函數(shù);9.2.1節(jié)。
[5] 只在全局作用域或名字空間里使用#include;9.2.1節(jié)。
[6] 只用#include包含完整的定義;9.2.1節(jié)。
[7] 使用包含保護(hù)符;9.3.3節(jié)。
[8] 用#include將C頭文件包含到名字空間里,以避免全局名字;8.2.9.1節(jié)、9.2.2節(jié)。
[9] 將頭文件做成自給自足的;9.2.3節(jié)。
[10] 區(qū)分用戶(hù)界面和實(shí)現(xiàn)界面;9.3.2節(jié)。
[11] 區(qū)分一般用戶(hù)界面和專(zhuān)家用戶(hù)界面;9.3.2節(jié)。
[12] 在有意向用于非C++程序組成部分的代碼中,應(yīng)避免需要運(yùn)行時(shí)初始化的非局部對(duì)象
;9.4.1節(jié)。
第10章忠告
[1] 用類(lèi)表示概念;10.1節(jié)。
[2] 只將public數(shù)據(jù)(struct)用在它實(shí)際上僅僅是數(shù)據(jù),而且對(duì)于這些數(shù)據(jù)成員并不存
在不變式的地方;10.2.8節(jié)。
[3] 一個(gè)具體類(lèi)型屬于最簡(jiǎn)單的類(lèi)。如果適用的話(huà),就應(yīng)該盡可能使用具體類(lèi)型,而不要
采用更復(fù)雜的類(lèi),也不要用簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu);10.3節(jié)。
[4] 只將那些需要直接訪(fǎng)問(wèn)類(lèi)的表示的函數(shù)作為成員函數(shù);10.3.2節(jié)。
[5] 采用名字空間,使類(lèi)與其協(xié)助函數(shù)之間的關(guān)系更明確;10.3.2節(jié)。
[6] 將那些不修改對(duì)象值的成員函數(shù)做成const成員函數(shù);10.2.6節(jié)。
[7] 將那些需要訪(fǎng)問(wèn)類(lèi)的表示,但無(wú)須針對(duì)特定對(duì)象調(diào)用的成員函數(shù)做成static成員函數(shù)
;10.2.4節(jié)。
[8] 通過(guò)構(gòu)造函數(shù)建立起類(lèi)的不變式;10.3.1節(jié)。
[9] 如果構(gòu)造函數(shù)申請(qǐng)某種資源,析構(gòu)函數(shù)就應(yīng)該釋放這一資源;10.4.1節(jié)。
[10] 如果在一個(gè)類(lèi)里有指針成員,它就需要有復(fù)制操作(包括復(fù)制構(gòu)造函數(shù)和復(fù)制賦值)
;10.4.4.1節(jié)。
[11] 如果在一個(gè)類(lèi)里有引用成員,它就可能需要有復(fù)制操作(復(fù)制構(gòu)造函數(shù)和復(fù)制賦值)
;10.4.6.3節(jié)。
[12] 如果一個(gè)類(lèi)需要復(fù)制操作或析構(gòu)函數(shù),它多半還需要有構(gòu)造函數(shù)、析構(gòu)函數(shù)、復(fù)制賦
值和復(fù)制構(gòu)造函數(shù);10.4.4.1節(jié)。
[13] 在復(fù)制賦值里需要檢查自我賦值;10.4.4.1節(jié)。
[14] 在寫(xiě)復(fù)制構(gòu)造函數(shù)時(shí),請(qǐng)小心地復(fù)制每個(gè)需要復(fù)制的元素(當(dāng)心默認(rèn)的初始式);1
0.4.4.1節(jié)。
[15] 在向某個(gè)類(lèi)中添加新成員時(shí),一定要仔細(xì)檢查,看是否存在需要更新的用戶(hù)定義構(gòu)造
函數(shù),以使它能夠初始化新成員;10.4.6.3節(jié)。
[16] 在類(lèi)聲明中需要定義整型常量時(shí),請(qǐng)使用枚舉;10.4.6.1節(jié)。
[17] 在構(gòu)造全局的和名字空間的對(duì)象時(shí),應(yīng)避免順序依賴(lài)性;10.4.9節(jié)。
[18] 用第一次開(kāi)關(guān)去緩和順序依賴(lài)性問(wèn)題;10.4.9節(jié)。
[19] 請(qǐng)記住,臨時(shí)對(duì)象將在建立它們的那個(gè)完整表達(dá)式結(jié)束時(shí)銷(xiāo)毀;10.4.10節(jié)。
第11章忠告
[1] 定義運(yùn)算符主要是為了模仿習(xí)慣使用方式;11.1節(jié)。
[2] 對(duì)于大型運(yùn)算對(duì)象,請(qǐng)使用const引用參數(shù)類(lèi)型;11.6節(jié)。
[3] 對(duì)于大型的結(jié)果,請(qǐng)考慮優(yōu)化返回方式;11.6節(jié)。
[4] 如果默認(rèn)復(fù)制操作對(duì)一個(gè)類(lèi)很合適,最好是直接用它;11.3.4節(jié)。
[5] 如果默認(rèn)復(fù)制操作對(duì)一個(gè)類(lèi)不合適,重新定義它,或者禁止它;11.2.2節(jié)。
[6] 對(duì)于需要訪(fǎng)問(wèn)表示的操作,優(yōu)先考慮作為成員函數(shù)而不是作為非成員函數(shù);11.5.2節(jié)
。
[7] 對(duì)于不訪(fǎng)問(wèn)表示的操作,優(yōu)先考慮作為非成員函數(shù)而不是作為成員函數(shù);11.5.2節(jié)。
[8] 用名字空間將協(xié)助函數(shù)與“它們的”類(lèi)關(guān)聯(lián)起來(lái);11.2.4節(jié)。
[9] 對(duì)于對(duì)稱(chēng)的運(yùn)算符采用非成員函數(shù);11.3.2節(jié)。
[10] 用()作為多維數(shù)組的下標(biāo);11.9節(jié)。
[11] 將只有一個(gè)“大小參數(shù)”的構(gòu)造函數(shù)做成explicit;11.7.1節(jié)。
[12] 對(duì)于非特殊的使用,最好是用標(biāo)準(zhǔn)string(第20章)而不是你自己的練習(xí);11.12節(jié)
。
[13] 要注意引進(jìn)隱式轉(zhuǎn)換的問(wèn)題;11.4節(jié)。
[14] 用成員函數(shù)表達(dá)那些需要左值作為其左運(yùn)算對(duì)象的運(yùn)算符;11.3.5節(jié)。
第12章忠告
[1] 避免類(lèi)型域;12.2.5節(jié)。
[2] 用指針和引用避免切割問(wèn)題;12.2.3節(jié)。
[3] 用抽象類(lèi)將設(shè)計(jì)的中心集中到提供清晰的界面方面;12.3節(jié)。
[4] 用抽象類(lèi)使界面最小化;12.4.2節(jié)。
[5] 用抽象類(lèi)從界面中排除實(shí)現(xiàn)細(xì)節(jié);12.4.2節(jié)。
[6] 用虛函數(shù)使新的實(shí)現(xiàn)能夠添加進(jìn)來(lái),又不會(huì)影響用戶(hù)代碼;12.4.1節(jié)。
[7] 用抽象類(lèi)去盡可能減少用戶(hù)代碼的重新編譯;12.4.2節(jié)。
[8] 用抽象類(lèi)使不同的實(shí)現(xiàn)能夠共存;12.4.3節(jié)。
[9] 一個(gè)有虛函數(shù)的類(lèi)應(yīng)該有一個(gè)虛析構(gòu)函數(shù);12.4.2節(jié)。
[10] 抽象類(lèi)通常不需要構(gòu)造函數(shù);12.4.2節(jié)。
[11] 讓不同概念的表示也不相同;12.4.1.1節(jié)。
第13章忠告
[1] 用模板描述需要使用到許多參數(shù)類(lèi)型上去的算法;13.3節(jié)。
[2] 用模板表述容器;13.2節(jié)。
[3] 為指針的容器提供專(zhuān)門(mén)化,以減小代碼規(guī)模;13.5節(jié)。
[4] 總是在專(zhuān)門(mén)化之前聲明模板的一般形式;13.5節(jié)。
[5] 在專(zhuān)門(mén)化的使用之前先聲明它;13.5節(jié)。
[6] 盡量減少模板定義對(duì)于實(shí)例化環(huán)境的依賴(lài)性;13.2.5節(jié)、C ..13.8節(jié)。
[7] 定義你所聲明的每一個(gè)專(zhuān)門(mén)化;13.5節(jié)。
[8] 考慮一個(gè)模板是否需要有針對(duì)C風(fēng)格字符串和數(shù)組的專(zhuān)門(mén)化;13.5.2節(jié)。
[9] 用表述策略的對(duì)象進(jìn)行參數(shù)化;13.4節(jié)。
[10] 用專(zhuān)門(mén)化和重載為同一概念的針對(duì)不同類(lèi)型的實(shí)現(xiàn)提供統(tǒng)一界面;13.5節(jié)。
[11] 為簡(jiǎn)單情況提供簡(jiǎn)單界面,用重載和默認(rèn)參數(shù)去表述不常見(jiàn)的情況;13.5節(jié)、13.4節(jié)
。
[12] 在修改為通用模板之前,在具體實(shí)例上排除程序錯(cuò)誤;13.2.1節(jié)。
[13] 如果模板定義需要在其他編譯單位里訪(fǎng)問(wèn),請(qǐng)記住寫(xiě)export;13.7節(jié)。
[14] 對(duì)大模板和帶有非平凡環(huán)境依賴(lài)性的模板,應(yīng)采用分開(kāi)編譯的方式;13.7節(jié)。
[15] 用模板表示轉(zhuǎn)換,但要非常小心地定義這些轉(zhuǎn)換;13.6.3.1節(jié)。
[16] 如果需要,用constraint()成員函數(shù)給模板的實(shí)參增加限制;13.9
[16],C.13.10節(jié)。
[17] 通過(guò)顯式實(shí)例化減少編譯和連接時(shí)間;C.13.10節(jié)。
[18] 如果運(yùn)行時(shí)的效率非常重要,那么最好用模板而不是派生類(lèi);13.6.1節(jié)。
[19] 如果增加各種變形而又不重新編譯是很重要的,最好用派生類(lèi)而不是模板;13.6.1節(jié)
。
[20] 如果無(wú)法定義公共的基類(lèi),最好用模板而不是派生類(lèi);13.6.1節(jié)。
[21] 當(dāng)有兼容性約束的內(nèi)部類(lèi)型和結(jié)構(gòu)非常重要時(shí),最好用模板而不是派生類(lèi);13.6.1節(jié)
。
第14章忠告
[1] 用異常做錯(cuò)誤處理;14.1節(jié)、14.5節(jié)、14.9節(jié)。
[2] 當(dāng)更局部的控制機(jī)構(gòu)足以應(yīng)付時(shí),不要使用異常;14.1節(jié)。
[3] 采用“資源申請(qǐng)即初始化”技術(shù)去管理資源;14.4節(jié)。
[4] 并不是每個(gè)程序都要求具有異常時(shí)的安全性;14.4.3節(jié)。
[5] 采用“資源申請(qǐng)即初始化”技術(shù)和異常處理器去維持不變式;14.3.2節(jié)。
[6] 盡量少用try塊,用“資源申請(qǐng)即初始化”技術(shù),而不是顯式的處理器代碼;14.4節(jié)。
[7] 并不是每個(gè)函數(shù)都需要處理每個(gè)可能的錯(cuò)誤;14.9節(jié)。
[8] 在構(gòu)造函數(shù)里通過(guò)拋出異常指明出現(xiàn)失?。?4.4.6節(jié)。
[9] 在從賦值中拋出異常之前,使操作對(duì)象處于合法狀態(tài);14.4.6.2節(jié)。
[10] 避免從析構(gòu)函數(shù)里拋出異常;14.4.7節(jié)。
[11] 讓main()捕捉并報(bào)告所有的異常;14.7節(jié)。
[12] 使正常處理代碼和錯(cuò)誤處理代碼相互分離;14.4.5節(jié)、14.5節(jié)。
[13] 在構(gòu)造函數(shù)里拋出異常之前,應(yīng)保證釋放在此構(gòu)造函數(shù)里申請(qǐng)的所有資源;14.4節(jié)。
[14] 使資源管理具有層次性;14.9節(jié)。
[15] 對(duì)于主要界面使用異常描述;14.9節(jié)。
[16] 當(dāng)心通過(guò)new分配的內(nèi)存在發(fā)生異常時(shí)沒(méi)有釋放,并由此而導(dǎo)致存儲(chǔ)的流失;14.4.1
節(jié)、14.4.2節(jié)、14.4.4節(jié)。
[17] 如果一函數(shù)可能拋出某個(gè)異常,就應(yīng)假定它一定會(huì)拋出這個(gè)異常;14.6節(jié)。
[18] 不要假定所有異常都是由exception類(lèi)派生出來(lái)的;14.10節(jié)。
[19] 庫(kù)不應(yīng)該單方面終止程序。相反,應(yīng)該拋出異常,讓調(diào)用者去做決定;14.1節(jié)。
[20] 庫(kù)不應(yīng)該生成面向最終用戶(hù)的錯(cuò)誤信息。相反,它應(yīng)該拋出異常,讓調(diào)用者去做決定
;14.1節(jié)。
[21] 在設(shè)計(jì)的前期開(kāi)發(fā)出一種錯(cuò)誤處理策略;14.9節(jié)。
第15章忠告
[1] 利用常規(guī)的多重繼承表述特征的合并;15.2節(jié)、15.2.5節(jié)。
[2] 利用多重繼承完成實(shí)現(xiàn)細(xì)節(jié)與界面的分離;15.2.5節(jié)。
[3] 用virtual基類(lèi)表達(dá)在類(lèi)層次結(jié)構(gòu)里對(duì)某些類(lèi)(不是全部類(lèi))共同的東西;15.2.5節(jié)。
[4] 避免顯式的類(lèi)型轉(zhuǎn)換(強(qiáng)制);15.4.5節(jié)。
[5] 在不可避免地需要漫游類(lèi)層次結(jié)構(gòu)的地方,使用dymamic_cast;15.4.1節(jié)。
[6] 盡量用dynamic_cast而不是typeid;15.4.4節(jié)。
[7] 盡量用private而不是protected;15.3.1.1節(jié)。
[8] 不要聲明protected數(shù)據(jù)成員;15.3.1.1節(jié)。
[9] 如果某個(gè)類(lèi)定義了operator delete( ),它也應(yīng)該有虛析構(gòu)函數(shù);15.6節(jié);
[10] 在構(gòu)造和析構(gòu)期間不要調(diào)用虛函數(shù);15.4.3節(jié)。
[11] 盡量少用為解析成員名而寫(xiě)的顯式限定詞,最好是在覆蓋函數(shù)里用它;15.2.1節(jié)。
第16章忠告
[1] 利用標(biāo)準(zhǔn)庫(kù)功能,以維持可移植性;16.1節(jié)。
[2] 決不要另行定義標(biāo)準(zhǔn)庫(kù)的功能;16.1.2節(jié)。
[3] 決不要認(rèn)為標(biāo)準(zhǔn)庫(kù)比什么都好。
[4] 在定義一種新功能時(shí),應(yīng)考慮它是否能夠納入標(biāo)準(zhǔn)庫(kù)所提供的框架中;16.3節(jié)。
[5] 記住標(biāo)準(zhǔn)庫(kù)功能都定義在名字空間std里;16.1.2節(jié)。
[6] 通過(guò)包含標(biāo)準(zhǔn)庫(kù)頭文件聲明其功能,不要自己另行顯示聲明;16.1.2節(jié)。
[7] 利用后續(xù)抽象的優(yōu)點(diǎn);16.2.1節(jié)。
[8] 避免肥大的界面;16.2.2節(jié)。
[9] 與自己寫(xiě)按照反向順序的顯式循環(huán)相比,最好是寫(xiě)利用反向迭代器的算法;16.3.2節(jié)
。
[10] 用base()從reverse_iterator抽取出iterator;16.3.2節(jié)。
[11] 通過(guò)引用傳遞容器;16.3.4節(jié)。
[12] 用迭代器類(lèi)型,如list::iterator,而不要采用索引容器元素的指針;16.3.1節(jié)。
[13] 在不需要修改容器元素時(shí),使用const迭代器;16.3.1節(jié)。
[14] 如果希望檢查訪(fǎng)問(wèn)范圍,請(qǐng)(直接或間接)使用at();16.3.3節(jié)。
[15] 多用容器和push_back()或resize(),少用數(shù)組和realloc();16.3.5節(jié)。
[16] vector改變大小之后,不要使用指向其中的迭代器;16.3.8節(jié)。
[17] 利用reserve()避免使迭代器非法;16.3.8節(jié)。
[18] 在需要的時(shí)候,reserve()可以使執(zhí)行情況更容易預(yù)期;16.3.8節(jié)。
第17章忠告
[1] 如果需要用容器,首先考慮用vector;17.1節(jié)。
[2] 了解你經(jīng)常使用的每個(gè)操作的代價(jià)(復(fù)雜性,大O度量);17.1.2節(jié)。
[3] 容器的界面、實(shí)現(xiàn)和表示是不同的概念,不要混淆;17.1.3節(jié)。
[4] 你可以依據(jù)多種不同準(zhǔn)則去排序和搜索;17.1.4.1節(jié)。
[5] 不要用C風(fēng)格的字符串作為關(guān)鍵碼,除非你提供了一種適當(dāng)?shù)谋容^準(zhǔn)則;17.1.4.1節(jié)。
[6] 你可以定義這樣的比較準(zhǔn)則,使等價(jià)的但是不相同的關(guān)鍵碼值映射到同一個(gè)關(guān)鍵碼;
17.1.4.1節(jié)。
[7] 在插入和刪除元素時(shí),最好是使用序列末端的操作(back操作);17.1.4.1節(jié)。
[8] 當(dāng)你需要在容器的前端或中間做許多插入和刪除時(shí),請(qǐng)用list;17.2.2節(jié)。
[9] 當(dāng)你主要通過(guò)關(guān)鍵碼訪(fǎng)問(wèn)元素時(shí),請(qǐng)用map或multimap;17.4.1節(jié)。
[10] 盡量用最小的操作集合,以取得最大的靈活性;17.1.1節(jié)。
[11] 如果要保持元素的順序性,選用map而不是hash_map;17.6.1節(jié)。
[12] 如果查找速度極其重要,選hash_map而不是map;17.6.1節(jié)。
[13] 如果無(wú)法對(duì)元素定義小于操作時(shí),選hash_map而不是map;17.6.1節(jié)。
[14] 當(dāng)你需要檢查某個(gè)關(guān)鍵碼是否在關(guān)聯(lián)容器里的時(shí)候,用find();17.4.1.6節(jié)。
[15] 用equal_range( ) 在關(guān)聯(lián)容器里找出所有具有給定關(guān)鍵碼的所有元素;17.4 ..1.6
節(jié)。
[16] 當(dāng)具有同樣關(guān)鍵碼的多個(gè)值需要保持順序時(shí),用multimap;17.4.2節(jié)。
[17] 當(dāng)關(guān)鍵碼本身就是你需要保存的值時(shí),用set或multiset;17.4.3節(jié)。
第18章忠告
[1] 多用算法,少用循環(huán);18.5節(jié)。
[2] 在寫(xiě)循環(huán)時(shí),考慮是否能將它表述為一個(gè)通用的算法;18.2節(jié)。
[3] 常規(guī)性地重溫算法集合,看看是不是能將新應(yīng)用變得更明晰;18.2節(jié)。
[4] 保證一對(duì)迭代器參數(shù)確實(shí)表述了一個(gè)序列;18.3.1節(jié)。
[5] 設(shè)計(jì)時(shí)應(yīng)該讓使用最頻繁的操作是簡(jiǎn)單而安全的;18.3節(jié)、18.3.1節(jié)。
[6] 把測(cè)試表述成能夠作為謂詞使用的形式;18.4.2節(jié)。
[7] 切記謂詞是函數(shù)和對(duì)象,不是類(lèi)型;18.4.2節(jié)。
[8] 你可以用約束器從二元謂詞做出一元謂詞;18.4.4.1節(jié)。
[9] 利用mem_fun()和mem_fun_ref()將算法應(yīng)用于容器;18.4.4.2節(jié)。
[10] 當(dāng)你需要將一個(gè)參數(shù)約束到一個(gè)函數(shù)上時(shí),用ptr_fun();18.4.4.3節(jié)。
[11] 切記strcmp()用0表示“相等”,與==不同;18.4.4.4節(jié)。
[12] 僅在沒(méi)有更特殊的算法時(shí),才使用for_each()和tranform();18.5.1節(jié)。
[13] 利用謂詞,以便能以各種比較準(zhǔn)則和相等準(zhǔn)則使用算法;18.4.2.1節(jié)、18.6.3.1節(jié)。
[14] 利用謂詞和其他函數(shù)對(duì)象,以使標(biāo)準(zhǔn)算法能用于表示范圍廣泛的意義;18.4.2節(jié)。
[15] 運(yùn)算符<和==在指針上的默認(rèn)意義很少適用于標(biāo)準(zhǔn)算法;18.6.3.1節(jié)。
[16] 算法并不直接為它們的參數(shù)序列增加或減少元素;18.6節(jié)。
[17] 應(yīng)保證用于同一個(gè)序列的小于和相等謂詞相互匹配;18.6.3.1節(jié)。
[18] 有時(shí)排好序的序列用起來(lái)更有效且優(yōu)雅;18.7節(jié)。
[19] 僅為兼容性而使用qsort()和bsearch();18.11節(jié)。
第19章忠告
[1] 在寫(xiě)一個(gè)算法時(shí),設(shè)法確定需要用哪種迭代器才能提供可接受的效率,并(只)使用
這種迭代器所支持的操作符去表述算法;19.2.1節(jié)。
[2] 當(dāng)給定的迭代器參數(shù)提供了多于算法所需的最小支持時(shí),請(qǐng)通過(guò)重載為該算法提供效
率更高的實(shí)現(xiàn);19.2.3節(jié)。
[3] 利用iterator_traits為不同迭代器類(lèi)別描述適當(dāng)?shù)乃惴ǎ?9.2.2節(jié)。
[4] 記住在istream_iterator和ostream_iterator的訪(fǎng)問(wèn)之間使用++;19.2.6節(jié)。
[5] 用插入器避免容器溢出;19.2.4節(jié)。
[6] 在排錯(cuò)時(shí)使用額外的檢查,后面只在必須時(shí)才刪除這些檢查;19.3.1節(jié)。
[7] 多用++p,少用p++;19.3節(jié)。
[8] 使用未初始化的存儲(chǔ)去改善那些擴(kuò)展數(shù)據(jù)結(jié)構(gòu)的算法的性能;19.4.4節(jié)。
[9] 使用臨時(shí)緩沖區(qū)去改善需要臨時(shí)數(shù)據(jù)結(jié)構(gòu)的算法的性能;19.4.4節(jié)。
[10] 在寫(xiě)自己的分配器之前三思;19.4節(jié)。
[11] 避免malloc()、free()、realloc()等;19.4.6節(jié)。
[12] 你可以通過(guò)為rebind所用的技術(shù)去模擬對(duì)模板的typedef;19.4.1節(jié)。
第20章忠告
[1] 盡量使用string操作,少用C風(fēng)格字符串函數(shù);20.4.1節(jié)。
[2] 用string作為變量或者成員,不作為基類(lèi);20.3節(jié)、25.2.1節(jié)。
[3] 你可以將string作為參數(shù)值或者返回值,讓系統(tǒng)去關(guān)心存儲(chǔ)管理問(wèn)題;20.3.6節(jié)。
[4] 當(dāng)你希望做范圍檢查時(shí),請(qǐng)用at()而不是迭代器或者[];20.3.2節(jié)、20.3.5節(jié)。
[5] 當(dāng)你希望優(yōu)化速度時(shí),請(qǐng)用迭代器或[]而不是at();20.3.2節(jié)、20.3.5節(jié)。
[6] 直接或者間接地使用substr()去讀子串,用replace()去寫(xiě)子串;20.3.12節(jié)、20.3.1
3節(jié)。
[7] 用find()操作在string里確定值的位置(而不是寫(xiě)一個(gè)顯式的循環(huán));20.3.11節(jié)。
[8] 在你需要高效率地添加字符時(shí),請(qǐng)?jiān)趕tring的后面附加;20.3.9節(jié)。
[9] 在沒(méi)有極端時(shí)間要求情況下用string作為字符輸入的目標(biāo);20.3.15節(jié)。
[10] 用string::npos表示“string的剩余部分”;20.3.5節(jié)。
[11] 如果必要,就采用低級(jí)操作去實(shí)現(xiàn)極度頻繁使用的string(而不是到處用低級(jí)數(shù)據(jù)結(jié)
構(gòu));20.3.10節(jié)。
[12] 如果你使用string,請(qǐng)?jiān)谀承┑胤讲蹲絣ength_error和out_of_range異常;20.3.5節(jié)
。
[13] 小心,不要將帶值0的char*傳遞給字符串函數(shù);20.3.7節(jié)。
[14] 只是到必須做的時(shí)候,(再)用c_str()產(chǎn)生string的C風(fēng)格表示;20.3.7節(jié)。
[15] 當(dāng)你需要知道字符的類(lèi)別時(shí),用isalpha()、isdigit()等函數(shù),不要自己去寫(xiě)對(duì)字符
值的檢測(cè);20.4.1節(jié)。
第21章忠告
[1] 在為用戶(hù)定義類(lèi)型的值定義<<和>>時(shí),應(yīng)該采用意義清晰的正文表示形式;21.2.3節(jié)
、21.3.5節(jié)。
[2] 在打印包含低優(yōu)先級(jí)運(yùn)算符的表達(dá)式時(shí)需要使用括號(hào);21.2節(jié)。
[3] 在添加新的<<和>>運(yùn)算符時(shí),你不必修改istream或ostream;21.2.3節(jié)。
[4] 你可以定義函數(shù),使其能基于第二個(gè)(或更后面的)參數(shù),具有像virtual函數(shù)那樣行
為;21.2.3.1節(jié)。
[5] 切記,按默認(rèn)約定>>跳過(guò)所有空格;21.3.2節(jié)。
[6] 使用低級(jí)輸入函數(shù)(如get()和read())主要是為了實(shí)現(xiàn)高級(jí)輸入函數(shù);21.3.4節(jié)。
[7] 在使用get()、getline()和read()時(shí)留心其終止準(zhǔn)則;21.3.4節(jié)。
[8] 在控制I/O時(shí),盡量采用操控符,少用狀態(tài)標(biāo)志;21.3.3節(jié)、21.4節(jié)、21.4.6節(jié)。
[9] (只)用異常去捕捉罕見(jiàn)的I/O錯(cuò)誤;21.3.6節(jié)。
[10] 聯(lián)結(jié)用于交互式I/O的流;21.3.7節(jié)。
[11] 使用哨位將許多函數(shù)的入口和出口代碼集中到一個(gè)地方;21.3.8節(jié)。
[12] 在無(wú)參數(shù)操控符最后不要寫(xiě)括號(hào);21.4.6.2節(jié)。
[13] 使用標(biāo)準(zhǔn)操控符時(shí)應(yīng)記住寫(xiě)#include ;21.4.6.2節(jié)。
[14] 你可以通過(guò)定義一個(gè)簡(jiǎn)單函數(shù)對(duì)象得到三元運(yùn)算符的效果(和效率);21.4.6.3節(jié)。
[15] 切記,width描述只應(yīng)用于隨后的一個(gè)I/O操作;21.4.4節(jié)。
[16] 切記precision描述只對(duì)隨后所有的浮點(diǎn)數(shù)輸出操作有效;21.4.3節(jié)。
[17] 用字符串流做內(nèi)存里的格式化;21.5.3節(jié)。
[18] 你可以描述一個(gè)文件流的模式;21.5.1節(jié)。
[19] 在擴(kuò)充I/O系統(tǒng)時(shí),應(yīng)該清楚地區(qū)分格式化(iostream)和緩沖(streambuf);21.
1節(jié)、21.6節(jié)。
[20] 將傳輸值的非標(biāo)準(zhǔn)方式實(shí)現(xiàn)為流緩沖區(qū);21.6.4節(jié)。
[21] 將格式化值的非標(biāo)準(zhǔn)方式實(shí)現(xiàn)為流操作;21.2.3節(jié)、21.3.5節(jié)。
[22] 你可以利用一對(duì)函數(shù)隔離和封裝起對(duì)用戶(hù)定義代碼的調(diào)用;21.6.4節(jié)。
[23] 你可以在讀入之前用in_avail()去確定輸入操作是否會(huì)被阻塞;21.6.4節(jié)。
[24] 劃分清楚需要高效的簡(jiǎn)單操作和實(shí)現(xiàn)某種策略的操作(將前者做成inline,將后者做
成virtual);21.6.4節(jié)。
[25] 用locale將“文化差異”局部化;21.7節(jié)。
[26] 用sync_with_stdio(x)去混合C風(fēng)格和C++風(fēng)格的I/O,或者離解C風(fēng)格和C++風(fēng)格的I/
O;21.8節(jié)。
[27] 當(dāng)心C風(fēng)格I/O的類(lèi)型錯(cuò)誤;21.8節(jié)。
第22章忠告
[1] 數(shù)值問(wèn)題常常很微妙。如果你對(duì)數(shù)值問(wèn)題的數(shù)學(xué)方面不是100 %有把握,請(qǐng)去找專(zhuān)家或
者做試驗(yàn);22.1節(jié)。
[2] 用numeric_limits去確定內(nèi)部類(lèi)型的性質(zhì);22.2節(jié)。
[3] 為用戶(hù)定義的標(biāo)量類(lèi)型描述numeric_limits;22.2節(jié)。
[4] 如果運(yùn)行時(shí)效率比對(duì)于操作和元素的靈活性更重要的話(huà),那么請(qǐng)用valarray去做數(shù)值
計(jì)算;22.4節(jié)。
[5] 用切割表述在數(shù)組的一部分上的操作,而不是用循環(huán);22.4.6節(jié)。
[6] 利用組合器,通過(guò)清除臨時(shí)量和更好的算法來(lái)獲得效率;22.4.7節(jié)。
[7] 用std::complex做復(fù)數(shù)算術(shù);22.5節(jié)。
[8] 你可以把使用complex類(lèi)的老代碼通過(guò)一個(gè)typedef轉(zhuǎn)為用std::complex模板;22.5節(jié)
。
[9] 在寫(xiě)循環(huán)從一個(gè)表出發(fā)計(jì)算某個(gè)值之前,先考慮一下accumulate()、inner_product(
)、partial_sum()和adjacent_difference();22.6節(jié)。
[10] 最好是用具有特定分布的隨機(jī)數(shù)類(lèi),少直接用rand();22.7節(jié)。
[11] 注意使你的隨機(jī)數(shù)充分隨機(jī);22.7節(jié)。
第23章忠告
[1] 知道你試圖達(dá)到什么目的;23.3節(jié)。
[2] 心中牢記軟件開(kāi)發(fā)是一項(xiàng)人的活動(dòng);23.2節(jié)、23.5.3節(jié)。
[3] 用類(lèi)比來(lái)證明是有意的欺騙;23.2節(jié)。
[4] 保持一個(gè)特定的實(shí)實(shí)在在的目標(biāo);23.4節(jié)。
[5] 不要試圖用技術(shù)方式去解決社會(huì)問(wèn)題;23.4節(jié)。
[6] 在設(shè)計(jì)和對(duì)待人員方面都應(yīng)該有長(zhǎng)期考慮;23.4.1節(jié)、23.5.3節(jié)。
[7] 對(duì)于什么程序在編碼之前先行設(shè)計(jì)是有意義的,在程序規(guī)模上并沒(méi)有下限;23.2節(jié)。
[8] 設(shè)計(jì)過(guò)程應(yīng)鼓勵(lì)反饋;23.4節(jié)。
[9] 不要將做事情都當(dāng)做取得了進(jìn)展;23.3節(jié)、23.4節(jié)。
[10] 不要推廣到超出了所需要的、你已有直接經(jīng)驗(yàn)的和已經(jīng)測(cè)試過(guò)的東西;23.4.1節(jié)、2
3.4.2節(jié)。
[11] 將概念表述為類(lèi);23.4.2節(jié)、23.4.3.1節(jié)。
[12] 系統(tǒng)里也存在一些不應(yīng)該用類(lèi)表述的性質(zhì);23.4.3.1節(jié)。
[13] 將概念間的層次關(guān)系用類(lèi)層次結(jié)構(gòu)表示;23.4.3.1節(jié)
[14] 主動(dòng)到應(yīng)用和實(shí)現(xiàn)中去尋找概念間的共性,將由此得到的一般性概念表示為基類(lèi);2
3.4.3.1節(jié)、23.4.3.5節(jié)。
[15] 在其他領(lǐng)域中的分類(lèi)方式未必適合作為應(yīng)用中的繼承模型的分類(lèi)方式;23.4.3.1節(jié)。
[16] 基于行為和不變式設(shè)計(jì)類(lèi)層次結(jié)構(gòu);23.4.3.1節(jié)、23.4.3.5節(jié)、23.4.3.7.1節(jié)。
[17] 考慮用例;23.4.3.1節(jié)。
[18] 考慮使用CRC卡片;23.4.3.1節(jié)。
[19] 用現(xiàn)存系統(tǒng)作為模型、靈感的源泉和出發(fā)點(diǎn);23.4.3.6節(jié)。
[20] 意識(shí)到視覺(jué)圖形工程的重要性;23.4.3.1節(jié)。
[21] 在原型成為負(fù)擔(dān)時(shí)就拋棄它;23.4.4節(jié)。
[22] 為變化而設(shè)計(jì),將注意力集中到靈活性、可擴(kuò)展性、可移植性和重用;23.4.2節(jié)。
[23] 將注意力集中到組件設(shè)計(jì);23.4.3節(jié)。
[24] 讓每個(gè)界面代表在一個(gè)抽象層次中的一個(gè)概念;23.4.3.1節(jié)。
[25] 面向變化進(jìn)行設(shè)計(jì),以求得穩(wěn)定性;23.4.2節(jié)。
[26] 通過(guò)將廣泛頻繁使用的界面做得最小、最一般和抽象來(lái)使設(shè)計(jì)穩(wěn)定;23.4.3.2、23.
4.3.5節(jié)。
[27] 保持盡可能小,不為“特殊需要”增加新特征;23.4.3.2節(jié)。
[28] 總考慮類(lèi)的其他表示方式。如果不可能有其他方式,這個(gè)類(lèi)可能就沒(méi)有代表某個(gè)清晰
的概念;23.4.3.4節(jié)。
[29] 反復(fù)評(píng)審、精化設(shè)計(jì)和實(shí)現(xiàn);23.4節(jié)、23.4.3節(jié)。
[30] 采用那些能用于調(diào)試,用于分析問(wèn)題、設(shè)計(jì)和實(shí)現(xiàn)的最好工具;23.3節(jié)、23.4.1節(jié)、
23.4.4節(jié)。
[31] 盡早、盡可能頻繁地進(jìn)行試驗(yàn)、分析和測(cè)試;23.4.4節(jié)、23.4.5節(jié)。
[32] 不要忘記效率;23.4.7節(jié)。
[33] 保持某種適合項(xiàng)目規(guī)模的規(guī)范性水平;23.5.2節(jié)。
[34] 保證有人負(fù)責(zé)項(xiàng)目的整體設(shè)計(jì);23.5.2節(jié)。
[35] 為可重用組件做文檔、推介和提供支持;23.5.1節(jié)。
[36] 將目標(biāo)與細(xì)節(jié)一起寫(xiě)進(jìn)文檔里;23.4.6節(jié)。
[37] 將為新開(kāi)發(fā)者提供的教學(xué)材料作為文檔的一部分;23.4.6節(jié)。
[38] 鼓勵(lì)設(shè)計(jì)、庫(kù)和類(lèi)的重用,并給予回報(bào);23.5.1節(jié)。
第24章忠告
[1] 應(yīng)該向數(shù)據(jù)抽象和面向?qū)ο蟪绦蛟O(shè)計(jì)的方向發(fā)展;24.2節(jié)。
[2] (僅僅)根據(jù)需要去使用C++的特征和技術(shù);24.2節(jié)。
[3] 設(shè)計(jì)應(yīng)與編程風(fēng)格相互匹配;24.2.1節(jié)。
[4] 將類(lèi)/概念作為設(shè)計(jì)中最基本的關(guān)注點(diǎn),而不是功能/處理;24.2.1節(jié)。
[5] 用類(lèi)表示概念;24.2.1節(jié)、24.3節(jié)。
[6] 用繼承(僅僅)表示概念間的層次結(jié)構(gòu)關(guān)系;24.2.2節(jié)、24.5.2節(jié)、24.3.2節(jié)。
[7] 利用應(yīng)用層靜態(tài)類(lèi)型的方式給出有關(guān)界面的更強(qiáng)的保證;24.2.2節(jié)。
[8] 使用程序生成器和直接界面操作工具去完成定義良好的工作;24.2.3節(jié)。
[9] 不要去使用那些與任何通用程序設(shè)計(jì)語(yǔ)言之間都沒(méi)有清晰界面的程序生成器或者直接
界面操作工具;24.2.4節(jié)。
[10] 保持不同層次的抽象相互分離;24.3.1節(jié)。
[11] 關(guān)注組件設(shè)計(jì);24.4節(jié)。
[12] 保證虛函數(shù)有定義良好的意義,每個(gè)覆蓋函數(shù)都實(shí)現(xiàn)預(yù)期行為;24.3.4節(jié)、24.3.2.
1節(jié)。
[13] 公用界面繼承表示的是“是一個(gè)”關(guān)系;24.3.4節(jié)。
[14] 成員表示的是“有一個(gè)”關(guān)系;24.3.4節(jié)。
[15] 在表示簡(jiǎn)單包容時(shí)最好用直接成員,不用指向單獨(dú)分配的對(duì)象的指針;24.3.3節(jié)、2
4.3.4節(jié)。
[16] 設(shè)法保證使用依賴(lài)關(guān)系為易理解的,盡可能不出現(xiàn)循環(huán),而且最??;24.3.5節(jié)。
[17] 對(duì)于所有的類(lèi),定義好不變式;24.3.7.1節(jié)。
[18] 顯式地將前條件、后條件和其他斷言表述為斷言(可能使用Assert());24.3.5節(jié)。
[19] 定義的界面應(yīng)該只暴露出盡可能少的信息;24.4節(jié)。
[20] 盡可能減少一個(gè)界面對(duì)其他界面的依賴(lài)性;24.4.2節(jié)。
[21] 保持界面為強(qiáng)類(lèi)型的;24.4.2節(jié)。
[22] 利用應(yīng)用層的類(lèi)型來(lái)表述界面;24.4.2節(jié)。
[23] 將界面表述得使請(qǐng)求可以傳遞給遠(yuǎn)程的服務(wù)器;24.4.2節(jié)。
[24] 避免肥大的界面;24.4.3節(jié)。
[25] 盡可能地使用private數(shù)據(jù)和成員函數(shù);24.4.2節(jié)。
[26] 用protected/public區(qū)分開(kāi)派生類(lèi)的設(shè)計(jì)者與一般用戶(hù)間的不同需要;24.4.2節(jié)。
[27] 使用模板去做通用型程序設(shè)計(jì);24.4.1節(jié)。
[28] 使用模板去做算法策略的參數(shù)化;24.4.1節(jié)。
[29] 如果需要在編譯時(shí)做類(lèi)型解析,請(qǐng)使用模板;24.4.1節(jié)。
[30] 如果需要在運(yùn)行時(shí)做類(lèi)型解析,使用類(lèi)層次結(jié)構(gòu);24.4.1節(jié)。
第25章忠告
[1] 應(yīng)該對(duì)一個(gè)類(lèi)的使用方式做出有意識(shí)的決策(作為設(shè)計(jì)師或者作為用戶(hù));25.1節(jié)。
[2] 應(yīng)注意到涉及不同種類(lèi)的類(lèi)之間的權(quán)衡問(wèn)題;25.1節(jié)。
[3] 用具體類(lèi)型去表示簡(jiǎn)單的獨(dú)立概念;25.2節(jié)。
[4] 用具體類(lèi)型去表示那些最佳效率極其關(guān)鍵的概念;25.2節(jié)。
[5] 不要從具體類(lèi)派生;25.2節(jié)。
[6] 用抽象類(lèi)去表示那些對(duì)象的表示可能變化的界面;25.3節(jié)。
[7] 用抽象類(lèi)去表示那些可能出現(xiàn)多種對(duì)象表示共存情況的界面;25.3節(jié)。
[8] 用抽象類(lèi)去表示現(xiàn)存類(lèi)型的新界面;25.3節(jié)。
[9] 當(dāng)類(lèi)似概念共享許多實(shí)現(xiàn)細(xì)節(jié)時(shí),應(yīng)該使用結(jié)點(diǎn)類(lèi);25.4節(jié)。
[10] 用結(jié)點(diǎn)類(lèi)去逐步擴(kuò)充一個(gè)實(shí)現(xiàn);25.4節(jié)。
[11] 用運(yùn)行時(shí)類(lèi)型識(shí)別從對(duì)象獲取界面;25.4.1節(jié)。
[12] 用類(lèi)去表示具有與之關(guān)聯(lián)的狀態(tài)信息的動(dòng)作;25.5節(jié)。
[13] 用類(lèi)去表示需要存儲(chǔ)、傳遞或者延遲執(zhí)行的動(dòng)作;25.5節(jié)。
[14] 利用界面類(lèi)去為某種新的用法而調(diào)整一個(gè)類(lèi)(不修改這個(gè)類(lèi));25.6節(jié)。
[15] 利用界面類(lèi)增加檢查,25.6節(jié)。
[16] 利用句柄去避免直接使用指針和引用;25.7節(jié)。
[17] 利用句柄去管理共享的表示;25.7節(jié)。
[18] 在那些能預(yù)先定義控制結(jié)構(gòu)的應(yīng)用領(lǐng)域中使用應(yīng)用框架;25.8節(jié)。
附錄B 忠告
[1] 要學(xué)習(xí)C++,應(yīng)該使用你可以得到的標(biāo)準(zhǔn)C++的最新的和完全的實(shí)現(xiàn); B.3節(jié)。
[2] C和C++的公共子集并不是學(xué)習(xí)C++時(shí)最好的開(kāi)始子集;1.6節(jié)、B.3節(jié)。
[3] 對(duì)于產(chǎn)品代碼,請(qǐng)記住并不是每個(gè)C++實(shí)現(xiàn)都是完全的最新的。在產(chǎn)品代碼中使用某個(gè)
新特征之前應(yīng)先做試驗(yàn),寫(xiě)一個(gè)小程序,測(cè)試你計(jì)劃使用的實(shí)現(xiàn)與標(biāo)準(zhǔn)的相符情況和性能
。例如,參見(jiàn)8.5[6~7]、16.5[10] 和B.5[7]。
[4] 避免被貶斥的特征,例如全局的static;還應(yīng)避免C風(fēng)格的強(qiáng)制;6.2.7節(jié)、B.2.3節(jié)。
[5]“隱含的int”已禁止,因此請(qǐng)明確描述每個(gè)函數(shù)、變量、const等的類(lèi)型;B.2.2節(jié)。
[6] 在將C程序轉(zhuǎn)為C++程序時(shí),首先保證函數(shù)聲明(原型)和標(biāo)準(zhǔn)頭文件的一致使用;B.
2.2節(jié)。
[7] 在將C程序轉(zhuǎn)為C++程序時(shí),對(duì)以C++關(guān)鍵字為名的變量重新命名;B.2.2節(jié)。
[8] 在將C程序轉(zhuǎn)為C++程序時(shí),將malloc()的結(jié)果強(qiáng)制到適當(dāng)類(lèi)型,或者將malloc()的所
有使用都改為new;B.2.2節(jié)。
[9] 在將malloc()和free()轉(zhuǎn)為new和delete時(shí),請(qǐng)考慮用vector、push_back()和reserv
e()而不是realloc();3.8節(jié)、16.3.5節(jié)。
[10] 在將C程序轉(zhuǎn)為C++程序時(shí),記住這里沒(méi)有從int到枚舉的隱式轉(zhuǎn)換;如果需要,請(qǐng)用
顯式轉(zhuǎn)換;4.8節(jié)。
[11] 在名字空間std里定義的功能都定義在無(wú)后綴的頭文件里(例如,std::cout聲明在里
)。早些的實(shí)現(xiàn)將標(biāo)準(zhǔn)庫(kù)功能定義在全局空間里,聲明在帶.h后綴的頭文件里(例如,st
d::cout聲明在里);9.2.2節(jié)、B.3.1節(jié)。
[12] 如果老的代碼檢測(cè)new的結(jié)果是否為0,那么必須將它修改為捕捉bad_alloc或者使用
new(nothrow);B.3.4節(jié)。
[13] 如果你用的實(shí)現(xiàn)不支持默認(rèn)模板參數(shù),請(qǐng)顯式提供參數(shù);用typedef可以避免重復(fù)寫(xiě)
模板參數(shù)(類(lèi)似于string的typedef使你無(wú)須寫(xiě)basic_string, allocator >);B.3.5節(jié)。
[14] 用得到std::string(里保存的是C風(fēng)格的串函數(shù));9.2.2節(jié)、B.3.1節(jié)。
[15] 對(duì)每個(gè)標(biāo)準(zhǔn)C頭文件,它將名字放入全局名字空間;與之對(duì)應(yīng)的頭文件將名字放入名
字空間std;B.3.1節(jié)。
[16] 許多系統(tǒng)有一個(gè)“String.h”頭文件里定義了一個(gè)串類(lèi)型。注意,這個(gè)串類(lèi)型與標(biāo)準(zhǔn)
庫(kù)的string不同。
[17] 盡可能使用標(biāo)準(zhǔn)庫(kù)功能,而不是非標(biāo)準(zhǔn)的功能;20.1節(jié)、B.3節(jié)、C.2節(jié)。
[18] 在聲明C函數(shù)時(shí)用extern "C";9.2.4節(jié)
附錄C 忠告
[1] 應(yīng)集中關(guān)注軟件開(kāi)發(fā)而不是技術(shù)細(xì)節(jié);C.1節(jié)。
[2] 堅(jiān)持標(biāo)準(zhǔn)并不能保證可移植性;C.2節(jié)。
[3] 避免無(wú)定義行為(包括專(zhuān)有的擴(kuò)充);C.2節(jié)。
[4] 將那些實(shí)現(xiàn)定義的行為局部化;C.2節(jié)。
[5] 在沒(méi)有{、}、[、]、|或!的系統(tǒng)里用關(guān)鍵字和二聯(lián)符表示程序,在沒(méi)有\(zhòng)的地方用三聯(lián)
符;C.3.1節(jié)。
[6] 為了方便通信,用ASCII字符去表示程序;C.3.3節(jié)。
[7] 采用符號(hào)轉(zhuǎn)義字符比用數(shù)值表示字符更好些;C.3.2節(jié)。
[8] 不要依賴(lài)于char的有符號(hào)或者無(wú)符號(hào)性質(zhì);C.3.4節(jié)。
[9] 如果對(duì)整數(shù)文字量的類(lèi)型感到有疑問(wèn),請(qǐng)使用后綴;C.4節(jié)。
[10] 避免破壞值的隱式轉(zhuǎn)換;C.6節(jié)。
[11] 用vector比數(shù)組好;C.7節(jié)。
[12] 避免union;C.8.2節(jié)。
[13] 用位域表示外部確定的布局;C.8.1節(jié)。
[14] 注意不同存儲(chǔ)管理風(fēng)格間的權(quán)衡;C.9節(jié)。
[15] 不要污染全局名字空間;C.10.1節(jié)。
[16] 在需要作用域(模塊)而不是類(lèi)型的地方,用namespace比class更合適;C.10.3節(jié)。
[17] 記住static類(lèi)成員需要定義;C.13.1節(jié)。
[18] 用typename消除對(duì)模板參數(shù)中類(lèi)型成員的歧義性;C.13.5節(jié)。
[19] 在需要用模板參數(shù)顯式限定之處,用template消除模板類(lèi)成員的歧義性;C.13.6節(jié)。
[20] 寫(xiě)模板定義時(shí),應(yīng)盡可能減少對(duì)實(shí)例化環(huán)境的依賴(lài)性;C.13.8節(jié)。
[21] 如果模板實(shí)例化花的時(shí)間過(guò)長(zhǎng),請(qǐng)考慮顯式實(shí)例化;C.13 ..10節(jié)。
[22] 如果需要編譯順序的顯式可預(yù)見(jiàn)性,請(qǐng)考慮顯式實(shí)例化;C.13.10節(jié)。
附錄D 忠告
[1] 應(yīng)預(yù)期每個(gè)直接與人打交道的非平凡程序或者系統(tǒng)都會(huì)用在多個(gè)國(guó)家;D.1節(jié)。
[2] 不要假定每個(gè)人使用的都是你所用的字符集;D.4.1節(jié)。
[3] 最好是用locale而不是寫(xiě)實(shí)質(zhì)性代碼去做對(duì)文化敏感的I/O;D.1節(jié)。
[4] 避免將現(xiàn)場(chǎng)名字字符串嵌入到程序正文里;D.2.1節(jié)。
[5] 盡可能減少全局格式信息的使用;D.2.3節(jié)、D.4.4.7節(jié)。
[6] 最好是用與現(xiàn)場(chǎng)有關(guān)的字符串比較和排序;D.2.4節(jié)、D.4.1節(jié)。
[7] 保存facet的不變性;D.2.2節(jié)、D.3節(jié)。
[8] 應(yīng)保證改變現(xiàn)場(chǎng)的情況只出現(xiàn)在程序里的幾個(gè)地方;D.2.3節(jié)。
[9] 利用現(xiàn)場(chǎng)去管理刻面的生存期;D.3節(jié)。
[10] 在寫(xiě)對(duì)現(xiàn)場(chǎng)敏感的I/O函數(shù)時(shí),記住去處理用戶(hù)(通過(guò)覆蓋)提供的函數(shù)所拋出的異
常;D.4.2.2節(jié)。
[11] 用簡(jiǎn)單的Money類(lèi)型保存貨幣值;D.4.3節(jié)。
[12] 要做對(duì)現(xiàn)場(chǎng)敏感的I / O,最好是用簡(jiǎn)單的用戶(hù)定義類(lèi)型保存所需的值(而不是從內(nèi)
部類(lèi)型的值強(qiáng)制轉(zhuǎn)換);D.4.3節(jié)。
[13] 在你對(duì)涉及到的所有因素有了很好的看法之前,不要相信計(jì)時(shí)結(jié)果;D.4.4.1節(jié)。
[14] 當(dāng)心time_t的取值范圍;D.4.4.1節(jié)、D.4.4.5節(jié)。
[15] 使用能接受多種輸入格式的日期輸入例程;D.4.4.5節(jié)。
[16] 最好采用那些明顯表明了所用現(xiàn)場(chǎng)的字符分類(lèi)函數(shù);D.4.5節(jié)、D.4.5.1節(jié)。
附錄E忠告
[1] 弄清楚你想要什么級(jí)別的異常時(shí)安全性;E.2節(jié)。
[2] 異常時(shí)安全性應(yīng)該是整體容錯(cuò)策略的一部分;E.2節(jié)。
[3] 為所有的類(lèi)提供基本保證,也就是說(shuō),維持一個(gè)不變式,而且不流失資源;E.2節(jié)、E
.3.2節(jié)、E.4節(jié)。
[4] 在可能和可以負(fù)擔(dān)之處提供強(qiáng)保證,使操作或者成功,或者保持所有操作對(duì)象不變;
E.2節(jié)、E.3節(jié)。
[5] 不要從析構(gòu)函數(shù)里拋出異常;E.2節(jié)、E.3.2節(jié)、E.4節(jié)。
[6] 不要從一個(gè)遍歷合法序列的迭代器里拋出異常;E.4.1節(jié)、E.4.4節(jié)。
[7] 異常時(shí)安全性涉及到仔細(xì)檢查各個(gè)操作;E.3節(jié)。
[8] 將模板設(shè)計(jì)為對(duì)異常透明的;E.3.1節(jié)。
[9] 更應(yīng)該用申請(qǐng)資源的構(gòu)造函數(shù)方式,不要采用init()函數(shù);E.3.5節(jié)。
[10] 為類(lèi)定義一個(gè)不變式,使什么是合法狀態(tài)變得非常清晰;E.2節(jié)、E.6節(jié)。
[11] 確??倢?duì)象放在合法狀態(tài)中,也不要怕拋出異常;E.3.2節(jié)、E.6節(jié)。
[12] 保持不變式簡(jiǎn)單;E.3.5節(jié)。
[13] 在拋出異常之前,讓所有操作對(duì)象都處于合法狀態(tài);E.2節(jié)、E.6節(jié)。
[14] 避免資源流失;E.2節(jié)、E.3.1節(jié)、E.6節(jié)。
[15] 直接表示資源;E.3.2節(jié)、E.6節(jié)。
[16] 記住swap()有時(shí)可以成為復(fù)制元素的替代方式;E.3.3節(jié)。
[17] 在可能時(shí)依靠操作的順序,而不是顯式地使用try塊;E.3.4節(jié)。
[18] 在替代物已經(jīng)安全生成之前不銷(xiāo)毀“老”信息;E.3.3節(jié)、E.6節(jié)。
[19] 依靠“資源申請(qǐng)即初始化”技術(shù);E.3節(jié)、E.3.2節(jié)、E.6節(jié)。
[20] 確保關(guān)聯(lián)容器的比較操作能夠復(fù)制;E.3.3節(jié)。
[21] 標(biāo)明關(guān)鍵性數(shù)據(jù)結(jié)構(gòu),并為它們定義能夠提供強(qiáng)保證的操作;E.6節(jié)。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。