2013-04-25 100 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. 
}; 
相关问题