【问题标题】:mutable with const pointer in C++在 C++ 中使用 const 指针可变
【发布时间】:2017-10-05 13:06:02
【问题描述】:

如果我像这样使用mutable 和const 指针:

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++ pointers constants mutable


【解决方案1】:

const int * ptr;

第一个是指向常量数据的指针,也就是说你可以改变指针和它指向的地方,但是你不能改变它指向的数据.

int * const ptr;

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

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

【讨论】:

    【解决方案2】:

    第二种情况会导致错误,因为mutable和const不能混用; mutable 只能与非常量数据成员一起使用。

    适用于非引用非 const 类型的非静态类成员,并指定该成员不影响类的外部可见状态(通常用于互斥锁、备忘录缓存、惰性求值和访问工具) . const 类实例的可变成员是可修改的。

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

    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;)也会导致同样的错误。

    【讨论】:

      【解决方案3】:
      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 是如何被应用的,那么请考虑有问题的那一行:

      mutable int * const ptr;
      

      这是说ptr both 是可变的(即使它所属的对象是 const 也可以被改变)和 const(不能即使它所属的对象是非 const 的,也会发生变异)。

      这两者显然是矛盾的。

      【讨论】:

        【解决方案4】:

        bugs.eclipse.org 说的:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-06-12
          • 1970-01-01
          • 1970-01-01
          • 2020-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多