c++ - 临时修改 const 成员函数中的字段

标签 c++ mutable const-cast

假设我们有一个类 A具有成员函数 f 。 对外,f只是计算一个值而不修改 A 的任何内容;但在实现中,它确实暂时修改了 A :

class A
{
    int f() const
    {
        tiny_change(b); // since copying "b" is expensive
        int result = compute(b);
        tiny_recover(b); // "b" backs to the original value
        return result;
    }

    B b;
}

当然上面的代码不能编译。这是我知道的两种解决方法:

  1. const_cast<A*>(this)->b
  2. mutable B b;

这些解决方案都不是完美的。当 A 的实例时,解决方案 1 涉及 UB本身就是const ;解决方案 2 将可变性暴露给整个类,从而无法防止编码器意外修改 b其他const成员函数。

const_cast是“本地”的,但可能会触发UB; mutable是内存安全的,但过于“全局”。

那么还有第三种解决方案,还是我理解有问题?

最佳答案

一种可能是将 B 封装在一个具有 mutable 的类中,但当它是 const 时,通常只允许 const 访问,只是它与 A::f 是 friend 。例如这样(未经测试的代码):

class A
{
  int f() const;
  int g() const; // some function without exclusive access

  class B_wrapper
  {
    friend int A::f() const;
  public:
    B& get() { return object; }
    B const& get() const { return object; }
  private:
    B& get_mutable() const { return object; }
    mutable B object;
  };
  B_wrapper bw;
};

int A::f() const
{
  B& b = bw.get_mutable(); // allowed due to friend declaration
  tiny_change(b); // since copying "b" is expensive
  int result = compute(b);
  tiny_recover(b); // "b" backs to the original value
  return result;
}

int A::g() const
{
  // B& b = bw.get_mutable();
  //   -> not allowed because B_wrapper::get_mutable() is private
  // B& b = bw.get();
  //   -> not allowed because get() const returns a const reference
  B const& b = bw.get();
  // without casts, only const interface to b is available
}

关于c++ - 临时修改 const 成员函数中的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40957207/

相关文章:

rust - 在循环中发生变异时,可变借用时间过长

c++ - wxWidgets connect() 无法识别事件类型

C++ - 带有和不带有 if 语句的奇怪时间测量

c++ - 在 C++ 中访问嵌套字典 unordered_map<string, void*>?

C++:为什么 const_cast 是邪恶的?

c++ - 为什么我不能 const_cast 转换运算符的返回值?

c++ - 具有不同 const 限定符的 2 种类型之间的转换

c++ - Linux fork/exec 到同一目录中的应用程序

python - Python 中的可变和不可变

Android 房间列表或可变列表返回类型