日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mutable、volatile的使用

發(fā)布時間:2023/12/10 编程问答 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mutable、volatile的使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文轉(zhuǎn)載自http://blog.csdn.net/tht2009/article/details/6920511

???????(1)mutable

?????? 在C++中,mutable是為了突破const的限制而設(shè)置的。被mutable修飾的變量,將永遠處于可變的狀態(tài),即使在一個const函數(shù)中,甚至結(jié)構(gòu)體變量或者類對象為const,其mutable成員也可以被修改。

struct ST{int a;mutable int b;};const ST st={1,2};st.a=11;//編譯錯誤st.b=22;//允許


???????mutable在類中只能夠修飾非靜態(tài)數(shù)據(jù)成員。mutable 數(shù)據(jù)成員的使用看上去像是騙術(shù),因為它能夠使const函數(shù)修改對象的數(shù)據(jù)成員。然而,明智地使用 mutable 關(guān)鍵字可以提高代碼質(zhì)量,因為它能夠讓你向用戶隱藏實現(xiàn)細節(jié),而無須使用不確定的東西。我們知道,如果類的成員函數(shù)不會改變對象的狀態(tài),那么這個成員函數(shù)一般會聲明成const的。但是,有些時候,我們需要在const的函數(shù)里面修改一些跟類狀態(tài)無關(guān)的數(shù)據(jù)成員,那么這個數(shù)據(jù)成員就應(yīng)該被mutalbe來修飾。

class ST{int a;mutable int showCount;void Show()const;…};ST::Show(){…//顯示代碼a=1;//錯誤,不能在const成員函數(shù)中修改普通變量showCount++;//正確}

?

???????const承諾的是一旦某個變量被其修飾,那么只要不使用強制轉(zhuǎn)換(const_cast),在任何情況下該變量的值都不會被改變,無論有意還是無意,而被const修飾的函數(shù)也一樣,一旦某個函數(shù)被const修飾,那么它便不能直接或間接改變?nèi)魏魏瘮?shù)體以外的變量的值,即使是調(diào)用一個可能造成這種改變的函數(shù)都不行。這種承諾在語法上也作出嚴格的保證,任何可能違反這種承諾的行為都會被編譯器檢查出來。

?????? mutable的承諾是如果某個變量被其修飾,那么這個變量將永遠處于可變的狀態(tài),即使在一個const函數(shù)中。這與const形成了一個對稱的定義,一個永遠不變,而另外一個是永遠可變。

?????? 看一個變量或函數(shù)是否應(yīng)該是const,只需看它是否應(yīng)該是constant或invariant,而看一個變量是否應(yīng)該是mutable,也只需看它是否是forever mutative。

?????? 這里出現(xiàn)了令人糾結(jié)的3個問題:

???????1、為什么要保護類的成員變量不被修改?

?????? 2、為什么用const保護了成員變量,還要再定義一個mutable關(guān)鍵字來突破const的封鎖線?

?????? 3、到底有沒有必要使用const 和 mutable這兩個關(guān)鍵字?

?????? 保護類的成員變量不在成員函數(shù)中被修改,是為了保證模型的邏輯正確,通過用const關(guān)鍵字來避免在函數(shù)中錯誤的修改了類對象的狀態(tài)。并且在所有使用該成員函數(shù)的地方都可以更準確的預測到使用該成員函數(shù)的帶來的影響。而mutable則是為了能突破const的封鎖線,讓類的一些次要的或者是輔助性的成員變量隨時可以被更改。沒有使用const和mutable關(guān)鍵字當然沒有錯,const和mutable關(guān)鍵字只是給了建模工具更多的設(shè)計約束和設(shè)計靈活性,而且程序員也可以把更多的邏輯檢查問題交給編譯器和建模工具去做,從而減輕程序員的負擔。

(2)volatile

?????? 象const一樣,volatile是一個類型修飾符。volatile修飾的數(shù)據(jù),編譯器不可對其進行執(zhí)行期寄存于寄存器的優(yōu)化。這種特性,是為了滿足多線程同步、中斷、硬件編程等特殊需要。遇到這個關(guān)鍵字聲明的變量,編譯器對訪問該變量的代碼就不再進行優(yōu)化,從而可以提供對特殊地址的直接訪問。

?????? volatile原意是“易變的”,但這種解釋簡直有點誤導人,應(yīng)該解釋為“直接存取原始內(nèi)存地址”比較合適。“易變”是相對與普通變量而言其值存在編譯器(優(yōu)化功能)未知的改變情況(即不是通過執(zhí)行代碼賦值改變其值的情況),而是因外在因素引起的,如多線程,中斷等。編譯器進行優(yōu)化時,它有時會取一些值的時候,直接從寄存器里進行存取,而不是從內(nèi)存中獲取,這種優(yōu)化在單線程的程序中沒有問題,但到了多線程程序中,由于多個線程是并發(fā)運行的,就有可能一個線程把某個公共的變量已經(jīng)改變了,這時其余線程中寄存器的值已經(jīng)過時,但這個線程本身還不知道,以為沒有改變,仍從寄存器里獲取,就導致程序運行會出現(xiàn)未定義的行為。并不是因為用volatile修飾了的變量就是“易變”了,假如沒有外因,即使用volatile定義,它也不會變化。而加了volatile修飾的變量,編譯器將不對其相關(guān)代碼執(zhí)行優(yōu)化,而是生成對應(yīng)代碼直接存取原始內(nèi)存地址。

???????一般說來,volatile用在如下的幾個地方:

???????1、中斷服務(wù)程序中修改的供其它程序檢測的變量需要加volatile;

?????? 2、多任務(wù)環(huán)境下各任務(wù)間共享的標志應(yīng)該加volatile;

?????? 3、存儲器映射的硬件寄存器通常也要加volatile說明,因為每次對它的讀寫都可能有不同意義;

???????使用該關(guān)鍵字的例子如下:

volatile int i=10;int a = i;...//其他代碼,并未明確告訴編譯器,對i進行過操作int b = i;

?

?????? volatile 指出 i是隨時可能發(fā)生變化的,每次使用它的時候必須從i的地址中讀取,因而編譯器生成的匯編代碼會重新從i的地址讀取數(shù)據(jù)放在b中。而優(yōu)化做法是,由于編譯器發(fā)現(xiàn)兩次從i讀數(shù)據(jù)的代碼之間的代碼沒有對i進行過操作,它會自動把上次讀的數(shù)據(jù)(即10)放在b中,而不是重新從i里面讀。這樣以來,如果i是一個寄存器變量或者表示一個端口數(shù)據(jù)就容易出錯,所以說volatile可以保證對特殊地址的直接訪問。

//addr為volatile變量 addr=0x57; addr=0x58;

?????? 如果上述兩條語句是對外部硬件執(zhí)行不同的操作,那么編譯器就不能像對待普通的程序那樣對上述語句進行優(yōu)化只認為“addr=0x58;”而忽略第一條語句(即只產(chǎn)生一條機器代碼),此時編譯器會逐一的進行編譯并產(chǎn)生相應(yīng)的機器代碼(兩條)。

???????volatile總是與優(yōu)化有關(guān),編譯器有一種技術(shù)叫做數(shù)據(jù)流分析,分析程序中的變量在哪里賦值、在哪里使用、在哪里失效,分析結(jié)果可以用于常量合并,常量傳播等優(yōu)化,進一步可以死代碼消除。但有時這些優(yōu)化不是程序所需要的,這時可以用volatile關(guān)鍵字禁止做這些優(yōu)化,它有下面的作用:
  1、不會在兩個操作之間把volatile變量緩存在寄存器中。在多任務(wù)、中斷等環(huán)境下,變量可能被其他的程序改變,編譯器自己無法知道,volatile就是告訴編譯器這種情況。
  2、不做常量合并、常量傳播等優(yōu)化,所以像下面的代碼,if的條件不會當作無條件真。?

volatile int i = 1; if (i > 0)...

?????? 3、對volatile變量的讀寫不會被優(yōu)化掉。如果你對一個變量賦值但后面沒用到,編譯器常常可以省略那個賦值操作,然而對Memory Mapped IO的處理是不能這樣優(yōu)化的。

?


總結(jié)

以上是生活随笔為你收集整理的mutable、volatile的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。