天天看點

Effective C++ 條款3——盡可能使用const

條款3:盡可能使用const

翻看自己的筆記,依然可以發現當時偷懶的痕迹,重新回顧将其寫成部落格,順帶将自己當初頭腦中的不解、迷惑以及謬論意義修改過來。 在C++中const這個關鍵字可以說出現的頻率太高了在上一篇中,簡介了一下const的注意事項,這裡首先對前一篇const做個總結: const出現在*星号左邊,表示被指物是常量;出現在 *星号右邊表示指針自身是常量,不過注意一下iterator(C++裡太多的這種例外,很是讨厭) 學過甚至接觸過STL的朋友們應該知道疊代器這個東西,就是iterator

std::vetcot<int> vec;
...
const std::vector<int>::iterator iter=vec.begin();//這裡iter相當于T* const
*iter=10;//OK,改變的是所指之物
++iter;//error,iter是const
std::vector<int>::const_iterator cIter=vec.begin();//相當于const T* 
*vIter=10;//error *cIter is const
++cIter;//OK
           

以上是針對資料的const,下面說說面對函數時const的使用。 大家一定見過類似于const int f()和int  () const的函數吧。          首先const 在前時,根據位置也能猜測,這個const指的是函數傳回值要是個常量,那麼為什麼呢????舉個例子(都是書中的例子,哈哈) 

class Rational{...};
const Rational operator* (const Rational& lhs,const Rational& rhs);
           

這是有個有理數類,然後呢重載了運算符*,姑且還當他還是普通的乘法就可以,lhs和rhs分别是左右操作數。此時呢我們這樣

Rational a,b,c;
.....
if((a*b)=c){...}
           

在這裡,如果int a,b,c 那麼(a*b)=c 一定會報錯。可是現在使我們自定義的類型a,b,c 那個const就可以達到和int這類内置類型一樣的效果,防止指派。那又會有人問,我們為什麼要指派呢???當然這個a*b=c很有可能是個書寫錯誤,我想敲擊代碼時==寫成=的人不止我一個吧。加上const之後就可以令編譯器在文法檢查時就發現這個錯誤,防止這個錯誤在後期帶來更大損失。學過軟體工程或有程式設計經驗的人都應該知道哦,錯誤與早發現,我們改的就越容易。         然後再說說const成員函數,也就是int  () const形式,這裡的const有兩點用處:         1、告訴類的使用者,這個函數不可以改動對象内容

        2、這個函數可以操縱const對象,使得代碼更高效。關于這一點,以後一會遇到,就是const引用或指針傳值(對象)的技術-----在條款20。 那麼什麼是不改變對象内容呢????也就是不更改對象内的任何bit...注意是bit(當然除了static變量,具體為什麼可以看看static的定義)。。編譯器就是這麼限制我們的 那麼如果為了某種合理需要,我硬是要更改對象内某個内容呢? 這裡呢引入mutable關鍵字

class X
{
public:
   bool GetFlag() const
   {
      m_accessCount++;
      return m_flag;
   }
private:
   bool m_flag;
   mutable int m_accessCount;
};

int main()
{
}
           

以上程式不會編譯出錯,因為m_accessCount被聲明為mutable。 還有一種情況就是,類中含有同一個成員函數的const和非const版本,此時它們的功能類似,必然有重複的代碼。在如此講究效率的c++語言中,這種情況要堅決抵制的。解決辦法就是用non-const版本調用const版本(千萬不要反過來)。

這是在一個類中
const char& operator[](std::size_t position) const
{
return text[position]
}
char& operator[](std::size_t position)
{
retrun const_cast<char&>(
static_cast<const TextBlock&>(*this)
[position]
);

           

其中static_cast是強制類型轉換(C++中的新形式),将*this從原始的TextBlock&轉換為const TextBlock&,這是安全的。然後又利用const_cast去除了const,為什麼如此麻煩,和兩次逆向的轉換不如不轉換是吧!!!NO,若不轉換,那麼non-const版本會一直遞歸調用自己。 至于為什麼不能反過來const版本調用non-const版本,這個仔細想想就能想明白的。我就不說了。 總之:       const可以幫助編譯器偵測出錯誤。       const和non-const成員函數有着實質等價的實作時,令non-const版本調用const版本可避免代碼重複

繼續閱讀