在 C++ 中使用 const 指针可变

mutable with const pointer in C++

提问人:Jayesh 提问时间:10/5/2017 最后编辑:Jayesh 更新时间:1/2/2022 访问量:2667

问:

如果我像这样使用指针:mutableconst

class Test
{
    public:
    mutable const int* ptr; // OK
};

它工作正常。

但是,如果我这样使用:

class Test
{
    public:
    mutable int * const ptr; // Error
};

错误:

prog.cpp:6:25: error: const 'ptr' cannot be declared 'mutable'
     mutable int * const ptr;
                         ^
prog.cpp: In function 'int main()':
prog.cpp:11:7: error: use of deleted function 'Test::Test()'
  Test t;
       ^
prog.cpp:3:7: note: 'Test::Test()' is implicitly deleted because the default definition would be ill-formed:
 class Test
       ^
prog.cpp:3:7: error: uninitialized const member in 'class Test'
prog.cpp:6:25: note: 'int* const Test::ptr' should be initialized
     mutable int * const ptr;

为什么编译器在第二种情况下会给出错误?

C++(英语:C++) 指针 常数 可变

评论

4赞 user7860670 10/5/2017
错误消息说什么?它可能值得一读。
0赞 Jayesh 10/5/2017
@VTT ide.geeksforgeeks.org/PWB4ti
2赞 Some programmer dude 10/5/2017
编辑您的问题以包含生成错误。逐字复制粘贴,作为文本,完整而完整。
0赞 n. m. could be an AI 10/5/2017
寻求调试帮助的问题(“为什么此代码不起作用?”)必须包括所需的行为、特定问题或错误以及在问题本身中重现它所需的最短代码。

答:

5赞 songyuanyao 10/5/2017 #1

第二种情况会导致错误,因为不能混合;可变只能与非 const 数据成员一起使用。mutableconst

适用于非引用非常量类型的非静态类成员,并指定该成员不影响类的外部可见状态(通常用于互斥锁、备注缓存、延迟计算和访问检测)。const 类实例的可变成员是可修改的。

顺便说一句,以下代码会导致相同的错误。

class Test
{
    public:
    mutable const int x; // Error;
    mutable int const x; // ditto;
};

第一种情况很好,因为它不是指针,而是指向 的指针。这意味着修改指针本身是可以的,您可以标记它。(但不能修改指针。const int*constconstmutable

顺便说一句,指向(例如)的指针也会导致相同的错误。constconstmutable const int* const ptr;

7赞 Some programmer dude 10/5/2017 #2

const int * ptr;

第一个是指向常量数据的指针,这意味着您可以更改指针及其指向的位置,但不能更改它指向的数据。

int * const ptr;

第二个是指向非常量数据的常量指针,这意味着您必须在构造函数中初始化指针,然后不能将其指向其他任何地方。但是,它指向的数据可以修改。

在这两种情况下,该部分都适用于指针,即实际的成员变量,而不是它指向的数据。由于变量不能同时是 ant 和 ant,因此您应该收到一条错误消息。mutablemutableconst

1赞 msc 10/5/2017 #3

bugs.eclipse.org 说:

可变说明符只能应用于类数据的名称 成员 (9.2),不能应用于声明为 const 或 static,不能应用于引用成员。

2赞 Useless 10/5/2017 #4
struct Test
{
    const int* ptr;
};

翻译:“结构有一个成员。成员是指针。指针指向一个整数,该整数可能无法通过指针进行更改。

不过,指针本身可能会发生突变,以指向不同的 .const int

如果我们选择非引用类型,可能会更简单,因此您可以将成员的类型(在您的示例中为指针)与指向对象的类型分开。

struct Test1
{
    int value;
};

现在,添加关键字以获得mutable

struct Test2
{
    mutable int value;
};

只是意味着我们被允许改变成员,即使结构本身是恒定的。

换句话说,在这两种情况下,所有这些都是可以的:

Test1 a { 123 };
Test2 b { 123 };

// now mutate the object through a non-const reference
a.value = 42;
b.value = 42;

但这是不同的:

const Test1& ca = a;
ca.value = 69; // NO, a member of a const object is const

const Test2& cb = b;
cb.value = 69; // OK, a mutable member of a const object

因此,现在我们了解了可变性的应用方式,请考虑有问题的行:

mutable int * const ptr;

这就是说,它是可变的(即使它所属的对象在其他方面是常量,也可以被变异)常量(即使它所属的对象在其他方面是非常量的,也不能被变异)。ptr

这两者显然是矛盾的。