http://blog.csdn.net/gmstart/article/details/7046140緩存
在C++的類定義裏面,能夠看到相似下面的定義:函數
07 |
int GetLength () const ; |
08 |
bool GetNodeInfo( const int index,Node & buffer) const {…… } |
09 |
bool DeleteNode( const int index); |
能夠看到,在GetLength和GetNodeInfo兩個成員函數的參數列表後面出現了一個const。這個const指明瞭這個函數不會修改該類的任何成員數據的值,稱爲常量成員函數。
對於const函數的外部定義,也不能忘記書寫const限定符,以下面給出GetLength函數(指返回鏈表的長度)的定義:spa
1 |
int List::GetLength() const |
若是在const成員函數的定義中出現了任何修改對象成員數據的現象,都會在編譯時被檢查出來,如:.net
1 |
int List::GetLength() const |
const成員函數存在的意義在於它能被const常對象調用。咱們都知道,在定義一個對象或者一個變量時,若是在類型前加一個const,如const int x;,則表示定義的量爲一個常量,它的值不能被修改。可是建立的對象卻能夠調用成員函數,調用的成員函數頗有可能改變對象的值,好比下面這段程序:code
顯然調用DeleteNode這個成員函數刪除一個鏈表結點後,頗有可能改變對象中length(鏈表長度)這個值,這不符合const對象的規定。可是,若是不容許const對象調用任何成員函數又是很是不合理的。因而,咱們把那些確定不會修改對象的各個屬性值的成員函數加上const說明符,這樣,在編譯時,編譯器將對這些const成員函數進行檢查,若是確實沒有修改對象值的行爲,則檢驗經過。之後,若是一個const常對象調用這些const成員函數的時候,編譯器將會容許。好比:orm
你可能會問,爲何不在一個const常對象調用成員函數的時候再進行檢查呢?若是被調用的函數會改變對象的屬性值,則當即打住就是了。這樣就不用麻煩地在成員函數後面加const限定符了。然而,這無疑會大大增長編譯時間。考慮下面這段代碼:對象
這段代碼中,GetLength被調用了兩次,可是編譯時卻也要檢查兩次,倘使一個成員函數被調用屢次,那麼他將在每次調用的時候都會被檢查。這顯然大大不利。而若是在定義類的時候加上const限定符對常函數加以標記,那麼編譯器只是檢查一次就好,在const對象調用成員函數時,const函數將會被直接放行。因此,C++採起了const限定符描述常函數方案而擯棄了後者。因此,即便一個函數沒有修改對象值的行爲,若是沒有加上const限定符說明是常函數,那麼const對象依然不能調用它。
然而,有些時候,咱們卻必需要讓const函數具備修改某個成員數據值的能力。好比一些內部的狀態量,對外部用戶無所謂,可是對整個對象的運行卻大有用處,如支持緩存的技術。遇到這種問題,咱們能夠把一個成員數據定義爲mutable(多變的),它表示這個成員變量能夠被const成員函數修改卻不違法。好比下面定義了一個is_valid類成員:blog
05 |
mutable bool is_valid; |
08 |
bool CheckList() const |
10 |
if (length >= 1) then return is_valid = true ; |
11 |
else return is_valid = false ; |
這樣,即便像CheckList這樣的const成員函數修改它也是合法的。
但須要注意的時,不可濫用mutabe描述符,若是在某個類中只有少數一部分是被容許const常量函數修改的,使用mutable是再合適不過的。若是大部分數據都定義爲mutable,那麼最好將這些須要修改的數據放入另外一個獨立的對象裏,並間接地訪問它。ip