在C++中可变的常量指针

5
如果我像这样在const指针上使用mutable

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;

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

4
错误信息会说些什么?阅读一下可能会很有价值。 - user7860670
@VTT http://ide.geeksforgeeks.org/PWB4ti - Jayesh
2
请编辑您的问题,包括构建错误。完整复制粘贴为文本形式。 - Some programmer dude
寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括期望的行为,具体的问题或错误以及在问题本身中重现所需的最短代码。 - n. m.
4个回答

7

const int * ptr;

这是一个指向常量数据的指针,意味着您可以更改指针及其指向,但无法更改其所指向的数据。

int * const ptr;

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

在两种情况下,mutable 部分都适用于指针,实际上是成员变量,而不是它所指向的数据。由于变量无法同时为 mutableconstant,因此应该会收到错误消息。


5
第二种情况会导致错误,因为mutableconst不能混用;mutable只能与非const数据成员一起使用。
适用于非引用非const类型的非静态类成员,并指定该成员不影响类的外部可见状态(通常用于互斥量、备忘缓存、惰性评估和访问检测)。const类实例的mutable成员是可修改的。
顺便说一下,以下代码会导致相同的错误。
class Test
{
    public:
    mutable const int x; // Error;
    mutable int const x; // ditto;
};

第一个情况是正确的,因为 const int* 不是一个 const 指针,而是指向 const 的指针。这意味着修改指针本身没有问题,并且您可以标记它为 mutable。 (但是您不能修改指针所指向的内容。)
另外,const 指针指向 const (例如,mutable const int* const ptr;)也会导致相同的错误。

2
struct Test
{
    const int* ptr;
};

翻译:

"这个结构体有一个成员,该成员是一个指针。指针指向一个整数,不允许通过指针改变整数的值。"

但是指针本身可以被更改,以指向另一个const int

如果我们选择一个非引用类型可能会更简单,这样你就可以将成员的类型(在你的例子中为指针)与指向对象的类型分开。

struct Test1
{
    int value;
};

现在,将 mutable 关键字添加到 get 函数中

struct Test2
{
    mutable int value;
};

这意味着即使结构本身是const,我们也可以更改成员。

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

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 是如何应用的,那么考虑一下有问题的那一行:

mutable int * const ptr;

这句话的意思是,ptr 是可变的(即使其所属对象是其他 const 的情况下,也能被改变),同时也是不可变的(即使其所属对象是非 const 的情况下,也无法被改变)。

这两者显然是相互矛盾的。


1

bugs.eclipse.org上说:

mutable修饰符只能应用于类数据成员的名称(9.2),不能应用于声明为const或static的名称,也不能应用于引用成员。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接