Const and mutable

Const and mutable

本文关键字:mutable and Const      更新时间:2023-10-16

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

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。这是如何编译的?

当成员变量没有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;
}

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

据说是在"抛弃CCD_ 9-内斯"。它基本上告诉编译器:取this指针(它的类型为temp const*,因为我们在tempconst成员函数中(,,并假设它的类型是temp*(子表达式(temp*)this(。然后,它指示编译器取消引用temp*类型的指针,以修改其成员之一。

去掉const-ness是在C++提供mutable关键字之前实现可变数据成员的方式。

正如你可能已经猜到的,这是一种糟糕的做法。这是一种糟糕的做法,因为它也可以用mutable修饰符来表达。这是一种糟糕的做法,因为它使用C型铸造的大炮,而C++const_cast<>就足够了。

最好的学习方法是开始把它变成一个琐碎的案例,看看它进展如何。

a( 如果你评论掉(*temp(,并把它变成this->value1=10;

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

b( 如果你注释掉可变关键字,你会得到相同的错误

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

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

如果您对我们为什么不能用正常的方式修改值感到困惑,请记住函数是const,const是一个承诺我们不应该在这里修改或分配任何值的约定(但是可变的(。因此,它基本上展示了两种打破承诺的技术或技巧:-(