條款1: 視c++爲語言聯邦
高效的c++在不同場景下,有不同的編寫範式或風格。沒有必要爲其規定統一格式,根據需要使用c++不同的特點去扮演不同的角色吧。
條款2:儘量以const、enum和inline替代define
使用define“定義”的常量對編譯器不可見,不會進入符號表,不便以後排錯,且會加大目標代碼量。使用define定義的函數宏也十分不便。
如何使用const定義和初始化不同類型的常量,也需要留意。還記得常量指針的定義嗎?
1. const int* p:p值的數據是常量;int * const p:p本身是常量,以及const int * const p。
2. 類內的const static成員在頭文件中定義,在源文件中初始化。
關於the enum hack的理解現在還不是很深:可以使用一個enum成員當做一個int的常量,使得程序可以順利編譯(如使用它作爲數組長度)
inline函數針對函數宏而言的,而它的主要目的是爲了規避函數調用的代價。inline函數的缺點呢? 過度使用inline函數會增加目標代碼量,還有呢?
條款3:儘可能使用const
感覺const爲用戶(調用者)做語義保證,當然離不開編譯器的支持。
到底有哪些地方可以使用const呢,一般的,比如全局和局部變量,類變量,函數參數,類方法;還有函數返回值,雖然這個自己不常用,但在STL卻大量出現。
編譯器保證const對象的bitwise constness,但是有時候我們需要改變對象的一些bit(呵呵,即內部狀態)而不影響外部表現,做到logic constness,這是就需要mutable關鍵字出場了,const成員函數可以改變有mutable修飾的成員變量。
另外,const屬性可以作爲函數簽名的一部分,參與重載。如f(const int)與f(int)是合法的重載函數。對一個const對象,訪問者只能調用它的const成員函數。如果你允許用戶定義一個const的對象,記得要爲其定義const函數。
4:確認對象使用前已進行初始化
這是常識。這裏補充一下c++如何初始化成員對象。
構造函數的初始化列表是其成員變量初始化的地方,而構造函數體則是在初始化後進一步處理的場所。如果不注意這些,在構造函數體內“初始化”成員對象,不僅造成效率問題,也使得const成員無法完成合適的初始化。
成員對象的初始化順序是先父類再子類,先早定義的後晚定義的(而不是按照初始化列表裏的順序)。
如果某個成員沒有出現在初始化列表內,則按照其默認構造函數進行初始化。