mutable關鍵字的用法

mutable關鍵字總是會和const關鍵字扯上關係,所以要使用mutable關鍵字前,你先要知道const關鍵字的用法。const關鍵字的使用方法這裡就不提了,這是閱讀本文的基礎知識。

關鍵字const的用途很廣,這裡我們只需專注在和mutable有關係的部份即可,那就是const member function。

; 範例1
class Sprite
{
public:
...
int getWidth() const;
int getHeight() const;
...
};

如範例所示,Sprite的getWidth和getHeight函式都是const,表示說呼叫到這二個函式的時候不會變動到任何這個Sprite物件內的資料。這是一般的情況。可是有時候我們所設計的介面,雖然在語意上它是const,但在實作上我們又不得不去變動到物件內部的某些資料。

; 範例2
class ResourceManager
{
public:
...
bool loadResource(string const& resName, ResourceItemHandle& item) const;
...
};

在範例中ResourceManager提供的loadResource函式,依照原始的設計,這個函式它會載入指定名稱的ResourceItem,而這個動作不會對ResourceManager內部產生任何變更。可是為了增加效率,我們在實作時在ResourceManager內部作了一個Cache的動作,把載入的ResourceItem快取起來,這樣下次再載入時就可以直接用比較快的速度完成載作動作。

這個時候就會產生如上所提到的和const衝突的情形,所以我們就只好把const修飾拿掉。拿掉const修飾字是一種解決的方法,但長遠來看這實在不是個好主意。解決的辨法是使用mutable關鍵字。

; 範例3
class ResourceManager
{
public:
...
bool loadResource(string const& resName, ResourceItemHandle& item) const;
...
private:
mutable ResourceItemCache cache ;
};

在範例3裡面,我們加了一個用來對ResourceItem作快取的member。loadResource函式被呼叫時會先在這裡面搜尋是否同一個resource已被載入過,如果是就不再作真正的載入動作直接拿cache內的資料來使用。要不然就執行真正的載入動作,載入成功後再把載入的ResourceItem存到cache內以備下次快速載入用。

在宣告cache時,我們對cache這個member加了mutable修飾字。這樣一來,loadResource就可以成功的通過編譯,即使它加了const修飾字。

這樣子你的程式就可以更有魯棒性了。

留言

這個網誌中的熱門文章

以lex/yacc實作算式計算機

猜數字遊戲 (電腦猜人)

KillSudoku 4顆星精彩數獨詳解 - 鍊技巧