在C ++中用const指针可变

时间:2017-10-05 13:06:03

标签: c++ pointers const mutable

如果我将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;

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

4 个答案:

答案 0 :(得分:4)

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

  

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

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

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

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

指向const的BTW const指针(例如mutable const int* const ptr;)也会导致同样的错误。

答案 1 :(得分:1)

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

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

两种情况下的mutable部分都适用于指针,实际的成员变量,而不是它指向的数据。并且由于变量不能同时变为可变和常量,因此您应该收到错误消息。

答案 2 :(得分:1)

bugs.eclipse.org说:

  

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

答案 3 :(得分:1)

struct Test
{
    const int* ptr;
};

翻译:“结构有一个成员。成员是一个指针。指针指向一个整数,它可能不会通过指针变异。”

指针本身可能会发生变异,指向不同的const int

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

struct Test1
{
    int value;
};

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

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(不是即使它是其成员的对象,也能够变异,否则是非常量的。)

这两者显然是矛盾的。