2013-04-25 46 views
1

我正在學習C++,我讀到:如果一個數據成員被聲明爲mutable,那麼從const成員函數中爲這個數據成員賦值是合法的。 但下面的代碼編譯沒有任何錯誤或由gcc警告。 (這是不是一個真實世界的代碼示例中,我只是寫它來測試可變關鍵字)由非const成員函數改變的可變變量

class M 
{ 
public: 
    M(){x=10;}; 
    int getX() {x++; return x;}; 
private: 
    mutable int x; 
}; 

int main() 
{ 
    M xx; 
    std::cout << xx.getX() << std::endl; 
} 

我不應該申報的getX爲const?

編輯1(永遠的答案,使事情變得更加清晰),下面的代碼不會被編譯

class M 
{ 
public: 
    M(){x=10;}; 
    int getX() const {x++; return x;}; 
private: 
    int x; 
}; 

int main() 
{ 
    M xx; 
    std::cout << xx.getX() << std::endl; 
} 
+3

該聲明並沒有說成員函數**必須是const。我建議在學習'mutable'之前學習和理解'const'。 – 2013-04-25 05:01:55

+0

通常情況下,const函數中允許的任何內容也允許在非const函數中使用。 Const函數比非const函數更具限制性。 – Spook 2013-04-25 05:09:15

+1

我的意思是沒有冒犯,但你如何評價你的英語理解?這裏的問題似乎是你對這句話的含義有一個基本的誤解。 – 2013-04-25 05:18:06

回答

3

這是法律修改mutables在const功能,當然是合法的修改mutables在non-const功能(每個non-const member-variable)。 mutable關鍵字允許在const函數中修改變量,但不會對在non-const函數中修改進行任何限制。

+0

這不是一個現實世界的代碼示例,我只是寫它來測試mutable關鍵字 – 2013-04-25 05:03:03

0

mutable通常用於允許const合格的成員函數修改緩存的數據。您可以將getX()聲明爲const並愉快地修改x,這就是mutable的用途。然而,通常認爲在成員函數中修改對象的內部狀態通常被認爲是一個壞主意,因爲它聲明瞭它沒有。

例如,您有一個基於容器內容計算值的const成員函數。如果容器有很多元素,則可能需要很長時間才能獲得結果。如果結果僅在您添加或刪除容器中的元素時發生變化,則可以將其緩存以備後用。由於成員函數是const限定的,因此您需要聲明結果變量爲mutable。由於可以從容器中的現有數據計算結果,所以緩存的值不被視爲對象內部狀態的一部分,並且由於const函數而被認爲可以對其進行修改。

int Foo::CalcResult() const 
{ 
    if(hasValidCache_ == false) 
    { 

     // ... recalc value ... 

     // Cache the result 
     hasValidCache = true; 
     cachedValue_ result; 
    } 

    return cachedValue_; 
} 
0

該聲明表示這一點。

class M 
{ 
public: 
    M(){x=10;}; 
    int getX() const 
//   ^^^^^ If a member function is const... 

        {x++; return x;}; 
//     ^^^ ...and it modifies a member variable... 
private: 
    mutable int x; 
// ^^^^^^^ ...then that variable must be mutable. 
}; 
相關問題