Const和可变

时间:2015-08-26 18:11:45

标签: c++

我刚刚看到这个代码片段,但我不明白它是如何编译的:

class temp {
    int value1; 
    mutable int value2;
public:
    void fun(int val) const
    {
        ((temp*) this)->value1 = 10;
        value2 = 10;
    }
};

这一行是什么意思

((temp*) this)->value1 = 10;

value1被分配到10,没有任何错误。但value1不是mutable。这是如何编译的?

2 个答案:

答案 0 :(得分:11)

当成员变量没有mutable限定符时,如果对象为const,则无法修改它。

当成员变量具有mutable限定符时,即使对象为const,也可以对其进行修改。

简单示例:

struct Foo
{
   int var1;
   mutable int var2;
};

const Foo f{};
f.var1 = 10; // Not OK
f.var2 = 20; // OK

当你有:

void fun(int val) const
{
    ((temp*) this)->value1 = 10;
    value2 = 10;
}

你绕过对象的const - 并以一种你不应该的方式改变它。这取决于未定义的行为。

就编译器而言,该代码等同于:

void fun(int val) const
{
    temp* ptr = (temp*)this

    // The compiler does not know how you got ptr.
    // It is able to modify value1 through ptr since ptr
    // points to a non-const object.
    ptr->value1 = 10;

    value2 = 10;
}

答案 1 :(得分:1)

最好的学习方法是开始把它变成一个微不足道的案例,看看它是怎么回事。

a)如果你注释掉(* temp)并做出类似的话 this-> value1 = 10;

  

错误:在只读结构中分配数据成员'temp :: value1'

b)如果你注释掉mutable关键字,你会得到同样的错误

  

错误:以只读方式分配数据成员“temp :: value2”   结构

如果您在上面阅读,R Sahu提供了关于可变关键字的正确答案。

如果你感到困惑,为什么我们不能用正常的方式修改值,记住函数是const和const是一个契约,承诺我们不应该在这里修改或赋值(但是可变)。所以它基本上显示了两种技术或黑客来打破承诺:-)