我正在学习C ++并且我读到了: 如果数据成员被声明为可变,那么从const成员函数为该数据成员赋值是合法的。 但是下面的代码编译没有任何错误或gcc的警告。 (这不是一个真实的代码示例,我只是编写它来测试mutable关键字)
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(ForEver的答案使事情更加清晰),以下代码将不会被编译:
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;
}
答案 0 :(得分:3)
修改const
函数中的mutable是合法的,当然修改non-const
函数中的mutable是合法的(每个non-const member-variable
)。 mutable
关键字允许在const
函数中修改变量,但不对non-const
函数中的修改提供任何限制。
答案 1 :(得分:0)
mutable
通常用于允许const
限定成员函数修改缓存数据。您可以将getX()
声明为const
并愉快地修改x
,这就是可变的内容。然而,通常认为修改成员函数中对象的内部状态是一个坏主意,因为它声明它没有。
例如,您有一个const成员函数,它根据容器的内容计算值。如果容器有很多元素,可能需要很长时间才能得到结果。如果结果仅在您从容器中添加或删除元素时发生更改,则可以将其缓存以供以后使用。由于成员函数是const限定的,因此您需要将结果变量声明为mutable
。由于结果可以从容器中的现有数据计算,因此缓存的值不被视为对象内部状态的一部分,从const函数开始,它被认为是可以修改它。
int Foo::CalcResult() const
{
if(hasValidCache_ == false)
{
// ... recalc value ...
// Cache the result
hasValidCache = true;
cachedValue_ result;
}
return cachedValue_;
}
答案 2 :(得分: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.
};