第11章 其它編程經(jīng)驗(yàn) 11.1 使用const提高函數(shù)的健壯性 const是constant的縮寫,“恒定不變”的意思。被const修飾的東西都受到強(qiáng)制保護(hù),可以預(yù)防意外的變動(dòng),能提高程序的健壯性。所以很多C++程序設(shè)計(jì)書籍建議:“Use const whenever you need”。 11.1.1 用const修飾函數(shù)的參數(shù) const只能修飾輸入?yún)?shù): 如果輸入?yún)?shù)采用“值傳遞”,由于函數(shù)將自動(dòng)產(chǎn)生臨時(shí)變量用于復(fù)制該參數(shù),該輸入?yún)?shù)本來(lái)就無(wú)需保護(hù),所以不要加const修飾。 例如不要將函數(shù)void Func1(int x) 寫成void Func1(const int x)。同理不要將函數(shù)void Func2(A a) 寫成void Func2(const A a)。其中A為用戶自定義的數(shù)據(jù)類型。 對(duì)于非內(nèi)部數(shù)據(jù)類型的參數(shù)而言,象void Func(A a) 這樣聲明的函數(shù)注定效率比較 為了提高效率,可以將函數(shù)聲明改為void Func(A &a),因?yàn)?#8220;引用傳遞”僅借用一下參數(shù)的別名而已,不需要產(chǎn)生臨時(shí)對(duì)象。但是函數(shù)void Func(A &a) 存在一個(gè)缺點(diǎn):“引用傳遞”有可能改變參數(shù)a,這是我們不期望的。解決這個(gè)問(wèn)題很容易,加const修飾即可,因此函數(shù)最終成為void Func(const A &a)。 以此類推,是否應(yīng)將void Func(int x) 改寫為void Func(const int &x),以便提高效率?完全沒(méi)有必要,因?yàn)閮?nèi)部數(shù)據(jù)類型的參數(shù)不存在構(gòu)造、析構(gòu)的過(guò)程,而復(fù)制也非常快,“值傳遞”和“引用傳遞”的效率幾乎相當(dāng)。 問(wèn)題是如此的纏綿,我只好將“const &”修飾輸入?yún)?shù)的用法總結(jié)一下,如表。 對(duì)于非內(nèi)部數(shù)據(jù)類型的輸入?yún)?shù),應(yīng)該將“值傳遞”的方式改為“const引用傳遞”,目的是提高效率。例如將void Func(A a) 改為void Func(const A &a)。 表11-1-1 “const &”修飾輸入?yún)?shù)的規(guī)則 如果給以“指針傳遞”方式的函數(shù)返回值加const修飾,那么函數(shù)返回值(即指針)的內(nèi)容不能被修改,該返回值只能被賦給加const修飾的同類型指針。 例如函數(shù) 如果函數(shù)返回值采用“值傳遞方式”,由于函數(shù)會(huì)把返回值復(fù)制到外部臨時(shí)的存儲(chǔ)單元中,加const修飾沒(méi)有任何價(jià)值。 函數(shù)返回值采用“引用傳遞”的場(chǎng)合并不多,這種方式一般只出現(xiàn)在類的賦值函數(shù)中,目的是為了實(shí)現(xiàn)鏈?zhǔn)奖磉_(dá)。 例如 如果將賦值函數(shù)的返回值加const修飾,那么該返回值的內(nèi)容不允許被改動(dòng)。上例中,語(yǔ)句 a = b = c仍然正確,但是語(yǔ)句 (a = b) = c 則是非法的。 11.1.3 const成員函數(shù) 以下程序中,類stack的成員函數(shù)GetCount僅用于計(jì)數(shù),從邏輯上講GetCount應(yīng)當(dāng)為const函數(shù)。編譯器將指出GetCount函數(shù)中的錯(cuò)誤。 int Stack::GetCount(void) const 11.2 提高程序的效率 全局效率是指站在整個(gè)系統(tǒng)的角度上考慮的效率,局部效率是指站在模塊或函數(shù)角度上考慮的效率。 【規(guī)則11-2-1】不要一味地追求程序的效率,應(yīng)當(dāng)在滿足正確性、可靠性、健壯性、可讀性等質(zhì)量因素的前提下,設(shè)法提高程序的效率。 【規(guī)則11-2-2】以提高程序的全局效率為主,提高局部效率為輔。 【規(guī)則11-2-3】在優(yōu)化程序的效率時(shí),應(yīng)當(dāng)先找出限制效率的“瓶頸”,不要在無(wú) 【規(guī)則11-2-4】先優(yōu)化數(shù)據(jù)結(jié)構(gòu)和算法,再優(yōu)化執(zhí)行代碼。 【規(guī)則11-2-5】有時(shí)候時(shí)間效率和空間效率可能對(duì)立,此時(shí)應(yīng)當(dāng)分析那個(gè)更重要,作出適當(dāng)?shù)恼壑?。例如多花費(fèi)一些內(nèi)存來(lái)提高性能。 【規(guī)則11-2-6】不要追求緊湊的代碼,因?yàn)榫o湊的代碼并不能產(chǎn)生高效的機(jī)器碼。 【建議11-3-2】變量(指針、數(shù)組)被創(chuàng)建之后應(yīng)當(dāng)及時(shí)把它們初始化,以防止把未被初始化的變量當(dāng)成右值使用。 【建議11-3-3】當(dāng)心變量的初值、缺省值錯(cuò)誤,或者精度不夠。 【建議11-3-4】當(dāng)心數(shù)據(jù)類型轉(zhuǎn)換發(fā)生錯(cuò)誤。盡量使用顯式的數(shù)據(jù)類型轉(zhuǎn)換(讓人們知道發(fā)生了什么事),避免讓編譯器輕悄悄地進(jìn)行隱式的數(shù)據(jù)類型轉(zhuǎn)換。 【建議11-3-5】當(dāng)心變量發(fā)生上溢或下溢,數(shù)組的下標(biāo)越界。 【建議11-3-6】當(dāng)心忘記編寫錯(cuò)誤處理程序,當(dāng)心錯(cuò)誤處理程序本身有誤。 【建議11-3-7】當(dāng)心文件I/O有錯(cuò)誤。 【建議11-3-8】避免編寫技巧性很高代碼。 【建議11-3-9】不要設(shè)計(jì)面面俱到、非常靈活的數(shù)據(jù)結(jié)構(gòu)。 【建議11-3-10】如果原有的代碼質(zhì)量比較好,盡量復(fù)用它。但是不要修補(bǔ)很差勁的代碼,應(yīng)當(dāng)重新編寫。 【建議11-3-11】盡量使用標(biāo)準(zhǔn)庫(kù)函數(shù),不要“發(fā)明”已經(jīng)存在的庫(kù)函數(shù)。 【建議11-3-12】盡量不要使用與具體硬件或軟件環(huán)境關(guān)系密切的變量。 【建議11-3-13】把編譯器的選擇項(xiàng)設(shè)置為最嚴(yán)格狀態(tài)。 【建議11-3-14】如果可能的話,使用PC-Lint、LogiScope等工具進(jìn)行代碼審查。 參考文獻(xiàn) |
|