我刚刚看到这个代码片段,但我不明白它是如何编译的:
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
。这是如何编译的?
答案 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是一个契约,承诺我们不应该在这里修改或赋值(但是可变)。所以它基本上显示了两种技术或黑客来打破承诺:-)