close
C++基本功:全面掌握constvolatilemutable關鍵字


     C++程式設計過程中,const的使用可以頻度是非常高的.它在保證程式安全方面起到了不可估量的作用.
用一句話來表達最確切不過了:」小兵立大功」.
  
有了const,那麼mutable當然缺不了.
  
然作為const的同胞兄弟,volatile卻在很多人的視野中消失.其實volatile擔負的責任有何嘗小呢?
  
自然,它們的用法多樣而靈巧,以至新手迷惑久久,下面就來系統的探討總結一下吧:

.一般應用
1.const
修飾各種變量的用法.
   a.
取代define
     #define D_INT 100
     #define D_LONG 100.29
     ………
     const int D_INT = 100;
     const D_INT = 100;     //
如果定義的int類型,可省略int.
     const long D_LONG = 100.29;
     ………
     const int& a = 100;
     const
替代define雖然增加分配空間,可它卻保證了類型安全.
    
C標準中,const定義的數據相當於全局的,C++中視宣告的位置而定.
   b.
修飾指標相關的變量
 
以三組簡單的定義示意:
     Group1:  

     int a = 0;   
     const int* b = &a;------------  [1]               
     int const *b = &a;------------  [2]                    
     const int* const b = &a;---- [4]  

     Group2: 

     const char *p = "const";--------------[1]
     char const *p = "const";--------------[2]  
     char* const p = "const";--------------[3]  
     const char * const p = "const";----[4]         

     Group3:

      int a=0;
      const int &b = a;---------------[1]
      int const &b = a;---------------[2] 
      int & const b = a;--------------[3]  //--->修飾引用時,const被忽略
      const int & const b = a;-----[4]

 總結:
     1.
如果const位於星號左側,const用來修飾指所指向的變量,
      
即指指向的為不可變的.
     2.
如果const位於星號右側,const就是修飾指標本身,即指本身是
 
不可變的.
      
因此,[1][2]的情況相同,所指向內容不可變(const放在變量
 
聲明符的位置無關),這種情況下不允許對內容進行更改,如不能*a = 3 ;
     3.[3]
中指本身是不可變的,而指所指向的內容是可變的,這種情況
 
下不能對指本身進行更改操作,a++是錯誤的
     4.[4]
中指本身和指向的內容均為常量.(引用特殊:引用在使用增加
 
遇義時,增加它代表的變量.所以qualifiers on reference are ignoredv.
      
延伸點:
      
注意範例:
       1.const int& reference = 1000;
       2.char* p = "const"
         char*& q ;
  
2.const
在函數環境下的各種應用
 
常用法示例如下:
   const A&  _Fun(const  A& _in);  //
修飾引用型傳入參數
   // A  _Fun(const A& _in);
   //A& _Fun(const A& _in);
   //
上面的兩種,在函數內部有特殊的步驟,這裡不詳提了…..
 
   const  A*  _Fun( const  A* _in);   //
修飾指針型傳入參數
   void _Fun( ) const;   //
修飾class成員函數
   const  A&  _Fun(A& _in );  //
修飾返回值
   const A & operator(const A& _in);  //
同時修飾傳入參數和返回值

   a.修飾參數
 
void _Fun(const A* _in) void _Fun(const A& _in);
    
它們被修飾後,在函數執行期間行為特性同於上面的講解,
    
注意:這不會改變原來數據的是否是const的屬性.

   b.修飾函數返回值
    const A&  _Fun( )
    const A*   _Fun( );
   
注意:由於生命期不同步的問題,不可將局部的變量的指或引用返回(static除外).
   
另外,傳出來的視情況,代表不同的意思…
 
對於A&返回類型,你若將之賦與其它變量,那麼它實際執行的是將返回的變量
    (
或引用)代表的數據賦出..而你若將其它值賦予之,那麼被賦予的是變量或引
 
用代表的數據. const A& 一般是防止之做為左值被賦值.

 這個地方還有很多的細節問題(譬如在連續賦值、返回的臨時物件的處理、
 
重載的const和非cosnt運算符等等),讀者自己在實踐中需要多多總結.

二、難點
3.
修飾類成員函數的const.
  
形如:void _Fun() const { };
  
你需要知道的幾點規則:

   a.const對象只能訪問const成員函數,而非const物件可以存取任意
 
的成員函數,包括const成員函數.
   b.const
物件的成員是不可修改的,然而const物件通過指維護的對象卻
 
是可以修改的.
   c.const
成員函數不可以修改物件的資料,不管對像是否具有const性質.它在
 
編譯時,以是否修改成員資料為依據,進行檢查.
   e.
然而加上mutable修飾符的資料成員,對於任何情況下通過任何手段
 
都可修改,自然此時的const成員函數是可以修改它的…

4.談談volatile和」完全const物件」
 
一個有volatile修飾的類只允許訪問其接口的一個子集,這個子集由類的
 
實現者來控制.用戶只有用const_cast才可以訪問這個類型的全部接口.而且,
 
const一樣,類的volatile屬性會傳遞給它的成員.想像const修飾的對
 
,它的成員變量是不可修改的,而它通過指針維護的對象或原生變量是可
 
修改.那麼我們想:如果對象維護一個char* ,則它相當於char*
  const chrptr ;
而不是const char* cosnt chrptr;對於類中的指針你需要
 
這樣修飾以防止它或它維護的資源:cosnt x* xptr;而不是x*const xptr;
 
因為cosnt 修飾的對像它默認 的行為是延續變量:x* cosnt xptr;

 更重要的,volatile修飾的數據,編譯器不可對其進行執行期寄存於寄存器的優化.
 
這種特性,是為了多線程同步的需要.有興趣者看參看AndreiGP系列文章.

5.談談const_cast轉換運算符
 
這個關鍵字最基礎的用法是:去掉數據的const性質.
 
值得注意的是:它只對指針、引用和其它的具有指向性質的類型.

參考:
    1.
Effective C++ 》關於const兩種語義的論述
    2.Andrei Alexandrescu
volatile——編寫多線程程序的好幫手》

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Bluelove1968 的頭像
    Bluelove1968

    藍色情懷

    Bluelove1968 發表在 痞客邦 留言(0) 人氣()