一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

C++ 基本功: 全面掌握const, volatile 和 mutable關(guān)鍵字

 WUCANADA 2012-12-21

C++基本功:全面掌握const、volatile和mutable關(guān)鍵字

 

CONST

一.一般應(yīng)用
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標(biāo)準(zhǔn)中,const定義的數(shù)據(jù)相當(dāng)于全局的,而C++中視聲明的位置而定.
   b.修飾指針相關(guān)的變量
以三組簡單的定義示意:
     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]  //--->修飾引用時(shí),const被忽略
     const int & const b = a;-----[4]
總結(jié):
     1.如果const位于星號左側(cè),則const用來修飾指針?biāo)赶虻淖兞?
即指針指向的為不可變的.
     2.如果const位于星號右側(cè),const就是修飾指針本身,即指針本身是
不可變的.
因此,[1]和[2]的情況相同,指針?biāo)赶騼?nèi)容不可變(const放在變量
聲明符的位置無關(guān)),
這種情況下不允許對內(nèi)容進(jìn)行更改,如不能*a = 3 ;
     3.[3]中指針本身是不可變的,而指針?biāo)赶虻膬?nèi)容是可變的,這種情況
下不能對指針本身
進(jìn)行更改操作,如a++是錯誤的
     4.[4]中指針本身和指向的內(nèi)容均為常量.(引用特殊:引用在使用增加
遇義時(shí),增加它代表的變量.所以qualifiers on reference are ignoredv.
延伸點(diǎn):
注意示例:
       1.const int& reference = 1000;
       2.char* p = "const"
         char*& q ;
2.const在函數(shù)環(huán)境下的各種應(yīng)用
常用法示例如下:
   const A&  _Fun(const  A& _in);  //修飾引用型傳入?yún)?shù)
   // A  _Fun(const A& _in);
   //A& _Fun(const A& _in);
   //上面的兩種,在函數(shù)內(nèi)部有特殊的步驟,這里不詳提了…..
   const  A*  _Fun( const  A* _in);   //修飾指針型傳入?yún)?shù)
   void _Fun( ) const;   //修飾class成員函數(shù)
   const  A&  _Fun(A& _in );  //修飾返回值
   const A & operator(const A& _in);  //同時(shí)修飾傳入?yún)?shù)和返回值

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

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

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

使用可變(mutable)成員隱藏實(shí)現(xiàn)細(xì)節(jié)
作者: Builder.com

鍵字 mutable 是一個奇怪的修飾符(specifier),它只能夠用于一個類的非靜態(tài)數(shù)據(jù)成員。下面我將討論 mutable 的語義和用法,但是首先我要解釋一下 C++ 對象模型的一個關(guān)鍵概念。

對象的狀態(tài)

一個對象的狀態(tài)由其非靜態(tài)數(shù)據(jù)成員的值構(gòu)成,因此,修改一個數(shù)據(jù)成員將會改變整個對象的狀態(tài)。將一個成員函數(shù)聲明為 const 能夠保證它不會改變對象的狀態(tài)。

然而在一些情況下,對象的邏輯狀態(tài)與基物理狀態(tài)之間可能有差別。例如,對于一個表示繪畫圖像的對象就存在這種情況。如果圖像還沒有更改,那 么我們就認(rèn)為其狀態(tài)沒有發(fā)生變化。然而,從底層實(shí)現(xiàn)方面來說,如果大對象在一段時(shí)間沒有活動,那么它們的內(nèi)存通常會被交換到一個文件中。交換一個圖像并不 會真地影響其狀態(tài),但是對象的一些數(shù)據(jù)成員可能會發(fā)生變化,在這里可能會發(fā)生變化的是指針、標(biāo)志位等。

在用戶調(diào)用一個諸如 Redraw() 之類的 const 成員函數(shù)時(shí),他們并不關(guān)心這個函數(shù)在內(nèi)部是如何實(shí)現(xiàn)的。從他們的角度來說,這個函數(shù)并不改變對象的邏輯狀態(tài),因此被聲明為 const。Redraw() 有可能修改對象的物理狀態(tài)這一事實(shí)是一個他們不應(yīng)該關(guān)心的實(shí)現(xiàn)細(xì)節(jié)。例如:

int Image::Redraw() const
{
 if (isLoaded==false)
 {
  //..read image data from a disk into a local buffer
  isLoaded=true; //changing a data member's value
 }
  //..paint image in the screen
}

class Image

可變(mutable)數(shù)據(jù)成員

如果嘗試編譯這段代碼,你會得到一個編譯錯誤。雖然 Redraw() 聲明為 const,但是它修改了一個數(shù)據(jù)成員。解決這個編譯錯誤的方法是將 isLoaded 聲明為一個 mutable 數(shù)據(jù)成員:

class Image
{
public:
 int Redraw() const;
 //..
private:
 mutable bool isLoaded;//can be changed by a const function
};

不像普通的數(shù)據(jù)成員,const 成員函數(shù)可以修改 mutable 數(shù)據(jù)成員。

Mutable 數(shù)據(jù)成員的使用看上去像是騙術(shù),因?yàn)樗軌蚴?const 函數(shù)修改對象的數(shù)據(jù)成員。然而,明智地使用 mutable 關(guān)鍵字可以提高代碼質(zhì)量,因?yàn)樗軌蜃屇阆蛴脩綦[藏實(shí)現(xiàn)細(xì)節(jié),而無須使用不確定的東西,比如 const_cast<>。

volatile關(guān)鍵字

  volatile是c/c++中一個鮮為人知的關(guān)鍵字,該關(guān)鍵字告訴編譯器不要持有變量的臨時(shí)拷貝,它可以適用于基礎(chǔ)類型
  如:int,char,long......也適用于C的結(jié)構(gòu)和C++的類。當(dāng)對結(jié)構(gòu)或者類對象使用volatile修飾的時(shí)候,結(jié)構(gòu)或者
  類的所有成員都會被視為volatile.

  使用volatile并不會否定對CRITICAL_SECTION,Mutex,Event等同步對象的需要
  例如:
  int i;
  i = i + 3;
  無論如何,總是會有一小段時(shí)間,i會被放在一個寄存器中,因?yàn)樗阈g(shù)運(yùn)算只能在寄存器中進(jìn)行。一般來說,volatitle
  關(guān)鍵字適用于行與行之間,而不是放在行內(nèi)。

  我們先來實(shí)現(xiàn)一個簡單的函數(shù),來觀察一下由編譯器產(chǎn)生出來的匯編代碼中的不足之處,并觀察volatile關(guān)鍵字如何修正
  這個不足之處。在這個函數(shù)體內(nèi)存在一個busy loop(所謂busy loop也叫做busy waits,是一種高度浪費(fèi)CPU時(shí)間的循環(huán)方法)

 void getKey(char* pch)
  {
  while (*pch == 0)
  ;
  }

  當(dāng)你在VC開發(fā)環(huán)境中將最優(yōu)化選項(xiàng)都關(guān)閉之后,編譯這個程序,將獲得以下結(jié)果(匯編代碼)

  ;       while (*pch == 0)
  $L27
  ; Load the address stored in pch
  mov eax, DWORD PTR _pch$[ebp]
  ; Load the character into the EAX register
  movsx eax, BYTE PTR [eax]
  ; Compare the value to zero
  test eax, eax
  ; If not zero, exit loop
  jne $L28
  ;
  jmp $L27
  $L28
  ;}

  這段沒有優(yōu)化的代碼不斷的載入適當(dāng)?shù)牡刂?,載入地址中的內(nèi)容,測試結(jié)果。效率相當(dāng)?shù)牡?,但是結(jié)果非常準(zhǔn)確

  現(xiàn)在我們再來看看將編譯器的所有最優(yōu)化選項(xiàng)開關(guān)都打開以后,重新編譯程序,生成的匯編代碼,和上面的代碼
  比較一下有什么不同

  ;{
  ; Load the address stored in pch
  mov eax, DWORD PTR _pch$[esp-4]
  ; Load the character into the AL register
  movsx al, BYTE PTR [eax]
  ; while (*pch == 0)
  ; Compare the value in the AL register to zero
  test al, al
  ; If still zero, try again
  je SHORT $L84
  ;
  ;}


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩精品一区二区毛片| 日韩一区欧美二区国产| 亚洲综合天堂一二三区| 日本精品免费在线观看| 精品香蕉国产一区二区三区| 自拍偷拍福利视频在线观看| 久久精品偷拍视频观看| 欧美一级不卡视频在线观看| 四十女人口红哪个色好看| 亚洲国产成人精品一区刚刚| 国产内射一级二级三级| 欧洲偷拍视频中文字幕| 精品精品国产自在久久高清| 免费观看在线午夜视频| 国产爆操白丝美女在线观看| 日本成人三级在线播放| 免费大片黄在线观看国语| 久热99中文字幕视频在线| 国产一区二区精品丝袜| 欧美日韩国产午夜福利| 日本加勒比在线播放一区| 麻豆tv传媒在线观看| 欧美大粗爽一区二区三区| 亚洲男人天堂网在线视频| 最近中文字幕高清中文字幕无| 人人妻在人人看人人澡| 久久99这里只精品热在线| 国产免费一区二区三区av大片| 成年午夜在线免费视频| 亚洲男人的天堂就去爱| 黄色国产精品一区二区三区| 中文字幕日韩欧美亚洲午夜| 久久福利视频视频一区二区 | 亚洲精品国产美女久久久99| 91久久精品国产一区蜜臀| 老司机精品视频在线免费看| 日韩性生活片免费观看| 女同伦理国产精品久久久| 日本男人女人干逼视频| 国产一区二区三区成人精品| 日韩在线欧美一区二区|