標籤:effective c++ 讀書筆記
- 仔細區別pointers和references。指標和引用有些相似,他們本身都是對存在於某個地方的對象(不是指class)的指示,但是他們有著本質的區別。指標變數儲存所指對象的地址,所指的對象可以是null,只要可以定址就行。而引用是某個已經存在對象的別名,所以不可以先聲明一個引用,經過一段時間(代碼)後讓它指向某個對象。
- 最好使用C++轉型操作符。C++提供了自己的四種轉型操作符:
1) static_cast。擁有與C舊式轉型相同的意義與限制,但不能移除運算式的常量性,因為有const_cast做這件事。
2) const_cast。只能用於改變運算式的常量性或變異性。
3) dynamic_cast。只能執行安全的向下轉型或跨系轉型。如果轉型失敗,會得到一個null指標或拋出異常。
4) reinterpret_cast。這是一個不具有移植性的轉型操作符,常見的用法是對函數指標進行轉型,但盡量少用。
使用這些新型轉型操作符的方式為:xxxx_cast<類型>(運算式)。從上面可以看出,使用新型轉型操作符可以更好地表達語義,增加可讀性,轉型操作也更加安全。即使使用了更安全的新型轉型操作符,轉型這種操作能不做就不做,《Effective C++》已經提過這一點。
- 絕對不要以多態方式處理數組。假設有一個雙層繼承體系class D : public B。另有一個接受B類型數組的函數,函數中依次對數組元素進行處理。如果以一個D類型的數組作為實參傳進去可以嗎?編譯是沒問題,數組做參數時與指標一樣的(實際上數組和指標有很多不同之處,具體可以見《C專家編程》),表示一個地址嘛。但是運行起來的時候就會出問題,因為指標的類型決定了對待指標指向的記憶體上的資料的方式,比如double型指標會以8位元組為單位對待指標指向的資料,而int型的指標是以4位元組為單位。那麼同樣對於D和B往往會出現他們大小不一樣,大小一樣,對待他們指向的記憶體的解決方式就不一樣,這就會出錯,別忘了可能出錯的地方就一定會出錯。這裡傳參是沒有問題的,但是函數在運行時會以B類型的方式對待傳進來的那個數組名,因而帶來了危險。那麼多態真的不可以用在數組上嗎?我認為可以,使用一個指標數組,而不要直接使用一個對象(class的執行個體)數組就可以了。本條款我想主要是針對對象數組的。
- 非必要不要提供default constructor。default constructor是指不帶任何參數的那麼constructor。這樣做可以增強安全性,某件商品通過標識號唯一標識,那麼構造一個沒有標識號的商品對象顯然就是錯誤的,所以default constructor就該被禁止,而要提供一個可以初始化商品標識號的constructor。但是沒有default constructor有時也會帶來不便,聲明對象數組時,使用STL容器時(STL容器要求放入其中的對象能夠提供default constructor)等等,然而提供default constructor也可能會帶來不便,比如可能由於提供了default constructor而在製作一些成員函數時需要檢查某些成員變數是否為初始變數或為其他值(假設每個成員變數都會被初始化《Effective C++》中已提及)。但是我覺得把事情做正確總是更重要的,耗費一點編程心力是值得的。對,安全至上。
《More Effective C++》重點摘要一:基礎議題