記錄一下《EffectiveC++簡體版》嚴重同意的條款
這個條款最好稱為:“盡量用編譯器而不用預處理”,因為#define經常被認為好象不是語言本身的一部分。這是問題之一。
在你打算用模板寫象max這樣有用的通用函數時,先檢查一下標准庫(見條款49),看看他們是不是已經存在。比如說上面說的max,你會驚喜地發現你可以後人乘涼:max是C++標准庫的一部分。
有了const和inline,你對預處理的需要減少了,但也不能完全沒有它。拋棄#include的日子還很遠,#ifdef/#ifndef在控制編譯的過程中還扮演重要角色。預處理還不能退休,但你一定要計劃給它經常放長假。
條款12: 盡量使用初始化而不要在構造函數裡賦值
請注意static類成員永遠也不會在類的構造函數初始化。靜態成員在程序運行的過程中只被初始化一次,所以每當類的對象創建時都去“初始化”它們沒有任何意義。至少這會影響效率:既然是“初始化”,那為什麼要去做多次?而且,靜態類成員的初始化和非靜態類成員有很大的不同,這專門有一個條款m47來說明。
條款22: 盡量用“傳引用”而不用“傳值”
c語言中,什麼都是通過傳值來實現的,c++繼承了這一傳統並將它作為默認方式。除非明確指定,函數的形參總是通過“實參的拷貝”來初始化的,函數的調用者得到的也是函數返回值的拷貝。
正如我在本書的導言中所指出的,“通過值來傳遞一個對象”的具體含義是由這個對象的類的拷貝構造函數定義的。這使得傳值成為一種非常昂貴的操作。
傳遞引用是個很好的做法,但它會導致自身的復雜性,最大的一個問題就是別名問題,這在條款17進行了討論。另外,更重要的是,有時不能用引用來傳遞對象,參見條款23。最後要說的是,引用幾乎都是通過指針來實現的,所以通過引用傳遞對象實際上是傳遞指針。因此,如果是一個很小的對象——例如int——傳值實際上會比傳引用更高效。
條款28: 劃分全局名字空間
全局空間最大的問題在於它本身僅有一個。在大的軟件項目中,經常會有不少人把他們定義的名字都放在這個單一的空間中,從而不可避免地導致名字沖突。
正因為這些限制,所以一旦編譯器支持,就要盡早使用真正的名字空間。
是的,我們同意C語言中變量要放在模塊頭部定義的規定;但在C++中,還是取消這種做法吧,它沒必要,不自然,而且昂貴。
還記得嗎?如果定義了一個有構造函數和析構函數的類型的變量,當程序運行到變量定義之處時,必然面臨構造的開銷;當變量離開它的生命空間時,又要承擔析構的開銷。這意味著定義無用的變量必然伴隨著不必要的開銷,所以只要可能,就要避免這種情況發生。
正如我所知道的,你的編程方式優雅而不失老練。所以你可能會在想,你決不會定義一個無用的變量,所以本條款的建議不適用於你嚴謹緊湊的編程風格。
推遲變量定義可以提高程序的效率,增強程序的條理性,還可以減少對變量含義的注釋。看來是該和那些開放式模塊的變量定義吻別了。
條款34: 將文件間的編譯依賴性降至最低
Lostmouse簡介
認識CSDN已經很久了,但開始寫技術文章不過是不久前的事,開辟這個專欄更是出於偶然。因為工作方面的原因,不能保證自己一直會有大塊的時間來維護這個專欄,但我會盡力。
至於Lostmouse本人,並非卡通中那只聰明可愛的小老鼠;相反,卻是一只將至而立卻還在迷惘的老貓:眼神固然明亮堅定,內心深處卻還不知道下一個目標在哪兒。貓的天性只是等待嗎?
作為一個程序員,很喜歡“程序人生”的說法:寫一段程序和親歷一段人生何其相似!只是,Lostmouse過去的程序裡濫用了太多的if, switch, break,甚至for(;;)。我期望,很快,自己寫出的程序更完美,更高效。
相片中是我和2歲的兒子斗斗,沒出現的另一位主角是我的妻子妞妞——正是有了你們,我才覺得我所做的一切都有了意義。
歡迎程序人生路上的每一位朋友和我聯系!
[email protected]
[email protected]
本文出自 “鍵碼視窗” 博客,謝絕轉載!