mutable與const修飾詞的對稱性
**ilemac
恐怕沒有程式設計師會反對在該使用const的地方使用const,但大部分程式設計師卻非常反對使用mutable,所以也很少注意mutable與const的對稱性。
我們知道,const是一種語義與語法統一得非常好的修飾詞,這在c++中其實並不多見,c++很多語法概念在語義上是模糊不清的,但const卻是乙個異數。const承諾的是一旦某個變數被其修飾,那麼只要不使用強制轉換,在任何情況下該變數的值都不會被改變,無論有意還是無意,而被const修飾的函式也一樣,一旦某個函式被const修飾,那麼它便不能直接或間接改變任何函式體以外的變數的值,即使是呼叫乙個可能造成這種改變的函式都不行。這種承諾在語法上也作出嚴格的保證,任何可能違反這種承諾的行為都會被編譯器檢查出來。
使用const,我們可以宣告一部分具有invariant性質的規格,這樣的例子有很多,本文不贅述了,本文重點論述以下mutable。
mutable雖然不如const受重視,但如同const一樣,mutable是c++中少有的一些具有清晰語義的修飾詞之一。
mutable的承諾是如果某個變數被其修飾,那麼這個變數將永遠處於可變的狀態,即使在乙個const函式中。這與const形成了乙個對稱的定義,乙個永遠不變,而另外乙個是永遠可變。
有某種說法是只有那些不改變物件外部行為特徵的內部變數才可以被宣告為mutable,其實不完全這樣。
這個世界有一些東西是永恆的,但有些東西又是永遠都處於變化中的,即使你將其他所有與之相關的東西都宣告為永恆,它依舊可以發生變化,因為一旦它變得永恆,那麼它所代表的東西也便失去了存在的意義,這便是mutable的含義。
乙個現成的例子便是scopeguard, 看過它的實現的讀者都知道,它主要的乙個類scopeguardimplbase中使用了mutable[2]:
class scopeguardimplbase
protected: scopeguardimplbase() : di**issed_(false) {} scopeguardimplbase(const scopeguardimplbase& other) : di**issed_(other.di**issed_) ~scopeguardimplbase() {} mutable bool di**issed_; private: // disable assignment scopeguardimplbase& operator=( const scopeguardimplbase&);};
在這個例子中我們可以看到,狀態變數di**issed被宣告成了mutable,我們姑且不管原作者的本意是否僅僅是作為一種技巧使用,目的是為了繞過必須const引用臨時變數的限制,我們只從語義學的角度考察,答案是明顯的,不管在任何情況下,di**issed都應該是可變的,否則整個scopeguard都失去了原意。它代表這樣一種規格:此型別(指scopeguard)的變數無法被宣告為const,(即使你做了這樣的宣告也是無效的)。
當然,同樣的規格也可以通過const作出,比如上例中如果不將函式di**iss()宣告為const,那麼也可基本表達同樣的規格,但問題在於,你不能假設使用者的使用環境,因為scopeguard定義為它可以在離開定義的區間時執行任何指定動作,而對動作本身並沒有做約束,因此你必須假定使用者也有可能將某個或某幾個scopeguard物件的引用傳入乙個const函式中(這樣做在某些情況中是有益的)。在這種條件下,mutable是必要的。
這樣的例子還可以舉出一些,比如乙個log物件,乙個constant的log物件是沒有意義的,它的儲存變數必須是mutable的。再比如乙個訪問計數器,某些特殊物件所擁有的dirty標誌等等。
而從語言的角度來看,有const就必須有mutable這樣完全相反的修飾子,否則便不成為乙個完全的劃分。
其實很難找到語義與語法結合的如此好的修飾詞了,你看乙個變數或函式是否應該是const,只需看它在你的設計空間中是否應該是constant或invariant,而看乙個變數是否應該是mutable,也只需看它是否在你的設計空間是forever mutative。
這種相反並且對稱的屬性,兩者交集為空,使得mutable能夠完全否定const作出的約束。二者組合使用,可以賦予乙個物件更多的規格選擇。而這種對稱,仔細品味,你會發現其含義餘味無窮,具有很強的審美性質。
1. iso/iec 14882, 「programming languages -c++, 1998
2. andrei alexandrescu and petru marginean ,「change the way you write exception-safe code — forever」,cuj, dec 2002
文章引用自:
const修飾指標與修飾常量
1.const 修飾指標 常量指標 eg const int p a 特點 指標的指向可以修改,但是指標指向的值不能修改 int a 10 int b 20 int p a p 20 錯誤 p b 正確 2.const 修飾常量 指標常量 eg int const p a 特點 指標的指向不能修改,...
mutable 修飾的變數
mutable 可以用來指出,即使結構或者類變數為const,其某個成員也可以被修改 在c 的類中,如果乙個函式被const 修飾,那麼它將無法修改其成員變數的,但是如果這個成員變數是被mutable修飾的話,則可以修改。例如 struct data char name 30 mutable int...
const修飾指標
1.指向const資料的非const指標 const int countptr 這個宣告從左到右讀,countptr 是乙個指向整數常量的指標 2.指向非const資料的const指標 int const ptr x 這個ptr指標就是const指標,宣告為const的指標必須在宣告時進行初始化。指...