單獨說說const關鍵字

const 是C++ 中常用的類型限定符,但我在工作中卻發現,許多人使用它僅僅是想當然,這樣有時也會用對,但在某些微妙的場合,可就沒有那麼幸運了。

究其實質原由,大多因爲沒有搞清const 類型限定符的本質。這裏我將對const 類型限定符進行一個分析,溯其本源究其本質,希望對大家理解const 有所幫助。

C++中爲什麼要引入 const

        C++ 的作者當初是出於怎樣的目的引入(或稱保留) const 關鍵字的呢?   這是一個有趣又有益的話題,對理解 const 很有幫助。

1。大家知道,C++ 有一個類型嚴格的編譯系統,這使得C++ 程序的錯誤在編譯階段即可發現許多,從而使出錯率大爲減少,

       也因此 成爲了C++ 與 C 相比有些突出優點的一個方面。

2。C 中很常見的預處理指令 #define  VariableName    VariableValue  可以很方便地進行值替換,這種替換在至少在以下三個方面

       優點表現突出:

  •  一是避免了意義模糊的數字出現,使得程序語義清晰流暢, 如下例: #define    USER_NUM_MAX     108    。這樣就避免了直接使用數字108帶來的困惑。
  •  二是可以很方便地進行參數的調整與修改。如上例,當人數由108變爲200時,在此改動一處就可。          
  •  三是提高了程序的執行效率。由於使用了預編譯器進行值替換,並不需要爲這些常量分配存儲空間,所以執行效率較高。

        鑑於以上的優點,這種預定義指令的使用在程序中隨處可見。

3。說到這裏,大家可能會迷惑上述所講的1、2兩點同 const 說明符有什麼關係。好,請接着下看:

       預處理語句雖然有些以上所述的許多優點,但它也有個比較致命的缺點。即,預處理語句僅僅只是簡單的值替換,缺少類型的檢測機制。

       這樣的預處理語句就可能享受 C++ 嚴格類型檢查的好處,從而可能成爲引發一系列錯誤的隱患。

4。好了,第一階段結論好了:

       結論:   const 說明符推出的初始目的,就是爲了取代預編譯指令 #define ,在繼承其優點的同時消除它的缺點。

       現在的它形式變成了:

                                               const   Tpye  VariableName = VariableValue;

       爲什麼 const 可以很好地取代預定義語句呢?  請看

       1、首先,以const  說明符修飾的常量值具有不可變性。這是它可取代預定義語句的基礎。

       2、第二,它也同樣可以避免意義模糊的數字出現,使得程序語義清晰的同時可以很方便地對參數進行調整與修改。

       3、第三,C++ 編譯器一般不爲普通 const 常量分配存儲空間,而是將們保存在符號表中,這使得它真正成爲了一個編譯期間常量。

                         由於 沒有了存儲與讀內存的操作,這使得它的效率也很高。這是它取代預定義語句的重要基礎。

       4、最後,const  定義也同一般普通的變量定義一樣,它會由編譯器對它進行類型的檢測。消除了預定義語句的隱患。

 

const 說明符使用情況分類詳析

1。const 說明符用於指針的兩種情況分析:

       int   a ;

       const  int   *p ;               //  指針類型爲 const   int *, 指針指向類型爲 const int  。指針變量爲非 const 類型,但指向的的變量爲 const 類型

       int  *const  p = &a  ;      //  指針類型爲int   *const , 指針指向   int  。指針變量爲 const 類型,指向的變量爲 非const 類型

 

        const 類型指針的轉換問題:

       1.、從" const 指針類型 " 到 " 非const 指針類型 " 的轉換:

               除了 const char * 指針類型 可轉換爲 char * 類型外(這是爲了對c語言的向下兼容)  ,

              任何的 const  type1 * 都不可轉換爲 type2 * 類型。

       2、從 " 非const 指針類型 " 到 " const 指針類型 " 的轉換:

              這樣的轉換都是可以執行的。

 

2。const 說明符限定函數的傳遞值參數:

       void  Fun( const  int  Var);

       分析:

                 上述寫法限定了參數Var不可在函數體內改變。而由值傳遞的特點可知,就算Var在函數體中改變了也不會影響到函數外部。

                 所以,此限定與函數的使用者無關,僅與函數的編寫者有關。

      結論:最好在函數的內部進行限定,對外部調用者屏蔽以免引起困惑。如可改寫如下:

                  void Fun( int Var)

                  {

                        const int &VarAlias = Var;

                        .....

                  }

3。const  限定函數的返回值類型

       const    int     Fun1();

       const    MyClass    Fun2();

       const    int    &Fun3();               

       cosnt    int    *Fun4();

       const    MyClass   &Fun5();    

       const   MyClass    *Fun6();

 

       分析:

                  上述寫法僅限定函數的返回值不可被改寫。

                  1.當函數返回爲內置類型的數據時,那已經是一個數值,那是必定不可改寫的,這時的const 可要可不要。但建議去掉。

                  2.當函數返回爲自定義類型的對象,這時的對象仍然可能包含可被賦值的數據成員,所以此時有意義。

                  3.如返回的是一個引用或是指針時,這種情況最爲常見,由地址變量的特點可知,適當使用const ,意義昭然。

4。const  限定類的成員函數

class ClassName

{
public:
     int Fun() const;

      .....
}

注意:

          採用這種const 後置的形式是一種規定,也是爲了不引起混淆。在這個函數的聲明和定義中均要使用const,因爲const已經成爲類型信息的一部分。 
          獲得能力:可以操作常量對象。
         失去能力:不能修改類的數據成員,不能在函數中調用其他不是const的函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章