【问题标题】:Mutable variable changed by a non-const member function由非常量成员函数更改的可变变量
【发布时间】:2013-04-18 20:57:19
【问题描述】:

我正在学习 C++,我读到:如果数据成员被声明为可变,那么从 const 成员函数为该数据成员赋值是合法的。强> 但是以下代码编译时没有任何错误或 gcc 警告。 (不是真实世界的代码示例,我只是为了测试 mutable 关键字而写的)

class M
{
public:
  M(){x=10;};
  int getX() {x++; return x;};
private:
  mutable int x;
};

int main()
{
  M xx;
  std::cout << xx.getX() << std::endl;
}

我不应该将 getX 声明为 const 吗?

编辑1(ForEver的回答让事情更清楚了),下面的代码将不会被编译

class M
{
public:
  M(){x=10;};
  int getX() const {x++; return x;};
private:
  int x;
};

int main()
{
  M xx;
  std::cout << xx.getX() << std::endl;
}

【问题讨论】:

  • 该语句并没有说成员函数必须是 const。建议先学习了解const再学习mutable
  • 通常情况下,在 const 函数中允许的任何内容也可以在非常量函数中使用。 const 函数比非 const 函数更具限制性。
  • 我无意冒犯,但您如何评价您的英语理解能力?这里的问题似乎是你对那句话的意思有一个基本的误解。
  • 你说得对,我的英语理解是个问题,但问起来很糟糕吗?无论如何。
  • 不,问没问题。我只是好奇。

标签: c++ mutable


【解决方案1】:

const 函数中修改可变变量是合法的,当然在non-const 函数中修改可变变量也是合法的(就像每个non-const member-variable 一样)。 mutable 关键字允许在 const 函数中修改变量,但对 non-const 函数中的修改没有任何限制。

【讨论】:

  • 这不是真实世界的代码示例,我只是为了测试可变关键字而写的
【解决方案2】:

mutable 通常用于允许const 限定的成员函数修改缓存数据。您可以将getX() 声明为const 并愉快地修改x,这就是mutable 的用途。然而,在成员函数中修改对象的内部状态通常被认为是一个坏主意,而它的声明表明它没有。

例如,您有一个 const 成员函数,它根据容器的内容计算一个值。如果容器有很多元素,可能需要很长时间才能得到结果。如果结果仅在您从容器中添加或删除元素时发生变化,您可以将其缓存以供以后使用。由于成员函数是 const 限定的,因此您需要将结果变量声明为 mutable。由于可以根据容器中的现有数据计算结果,因此缓存值不被视为对象内部状态的一部分,并且由于 const 函数而可以对其进行修改。

int Foo::CalcResult() const
{
    if(hasValidCache_ == false)
    {

        // ... recalc value ...

        // Cache the result
        hasValidCache = true;
        cachedValue_ result;
    }

    return cachedValue_;
}

【讨论】:

    【解决方案3】:

    声明就是这个意思。

    class M
    {
    public:
       M(){x=10;};
       int getX() const
     //           ^^^^^ If a member function is const...
    
                       {x++; return x;};
     //                 ^^^ ...and it modifies a member variable...
    private:
       mutable int x;
    // ^^^^^^^ ...then that variable must be mutable.
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-24
      • 2012-12-13
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      • 2011-11-15
      • 2019-07-09
      • 1970-01-01
      相关资源
      最近更新 更多