简体   繁体   English

在C ++中用const指针可变

[英]mutable with const pointer in C++

If I use mutable with const pointer like this: 如果我使用mutableconst这样的指针:

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

It's working fine. 它工作正常。

But, If I use like this : 但是,如果我这样使用:

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

An 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;

Why does compiler give an error in second case? 为什么编译器在第二种情况下会出错?

The 2nd case causes error because mutable and const can't be mixed; 第二种情况会导致错误,因为mutableconst不能混合; mutable can only be used with non-const data member. mutable只能与非const数据成员一起使用。

applies to non-static class members of non-reference non-const type and specifies that the member does not affect the externally visible state of the class (as often used for mutexes, memo caches, lazy evaluation, and access instrumentation). 适用于非引用非const类型的非静态类成员,并指定该成员不会影响类的外部可见状态(通常用于互斥,备忘录缓存,延迟评估和访问检测)。 mutable members of const class instances are modifiable. const类实例的可变成员是可修改的。

BTW the following code causes the same error. BTW以下代码导致相同的错误。

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

The 1st case is fine, because const int* is not a const pointer, but a pointer to const . 第一种情况很好,因为const int*不是const指针,而是指向const的指针。 That means it's fine to modify the pointer itself, and you can mark it mutable . 这意味着修改指针本身很好,你可以将其标记为mutable (But you can't modify the pointee.) (但你无法修改指针。)

BTW const pointer to const (eg mutable const int* const ptr; ) causes the same error too. 指向const BTW const指针(例如, mutable const int* const ptr; )也会导致相同的错误。

The first is a pointer to constant data, which means you can change the pointer and where it points, but you can't change the data it points to. 第一个是指向常量数据的指针,这意味着您可以更改指针及其指向的位置,但您无法更改它指向的数据。

The second is a constant pointer to non-constant data, which means you must initialize the pointer in your constructor(s) and then you can't make it point anywhere else. 第二个是指向非常量数据的常量指针 ,这意味着您必须在构造函数中初始化指针,然后您无法将其指向其他位置。 The data it points to can be modified though. 它可以修改它指向的数据。

The mutable part in both cases applies to the pointer , the actual member variable , not the data it points to. 两种情况下的mutable部分都适用于指针 ,实际成员变量 ,而不是它指向的数据。 And since the variable can't be both mutable and constant at the same time you should get an error message for that. 并且因为变量不能同时是可变的和常量的,所以你应该得到一个错误消息。

The bugs.eclipse.org say's: bugs.eclipse.org说:

The mutable specifier can be applied only to names of class data members (9.2) and cannot be applied to names declared const or static, and cannot be applied to reference members. 可变说明符只能应用于类数据成员(9.2)的名称, 不能应用于声明为const或static的名称,也不能应用于引用成员。

struct Test
{
    const int* ptr;
};

Translation: "The structure has a member. The member is a pointer. The pointer points to an integer which may not be mutated via the pointer." 翻译: “结构有一个成员。成员是一个指针。指针指向一个整数,它可能不会通过指针变异。”

The pointer itself may be mutated though, to point to a different const int . 指针本身可能会发生变异,指向不同的const int

It's probably simpler if we pick a non-reference type, so you can separate the types of the member (in your example a pointer), from the type of the pointed-to object. 如果我们选择一个非引用类型,它可能更简单,因此您可以将成员的类型(在您的示例中为指针)与指向对象的类型分开。

struct Test1
{
    int value;
};

Now, adding the mutable keyword to get 现在,添加mutable关键字来获取

struct Test2
{
    mutable int value;
};

just means we're allowed to mutate the member even when the structure itself is otherwise const . 只是意味着即使结构本身是const,我们也可以改变成员。

In other words, all of this is OK in both cases: 换句话说,在这两种情况下,所有这些都可以:

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

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

but this is different: 但这是不同的:

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

So, now that we understand how mutable is being applied, the consider the problematic line: 所以,既然我们已经了解了如何应用mutable,那么考虑一下有问题的一行:

mutable int * const ptr;

This is saying that ptr is both mutable (able to be mutated even when the object it's a member of is otherwise const) and const (not able to be mutated even when the object it's a member of is otherwise non-const). 这就是说ptr 既可变(也可以变异,即使它是其成员的对象,否则是const) const(即使当它是其成员的对象是非const时也不能变异)。

The two are obviously contradictory. 这两者显然是矛盾的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM