有一个修改 'scratchpad' 变量的 const 函数是否正确?

Is it correct to have a const function which modified a 'scratchpad' variable?

我会描述问题。我有一个带有 API 的 class,它调用 class 成员函数的大型层次结构来执行一些逻辑。现在,我更新了逻辑,因此层次结构中的每个函数都需要一个额外的参数(API 没有改变)。

一个想法 - 我可以向 class 添加一个 'scrathpad' 成员,而不是为每个方法添加一个额外的参数,即一个仅用于临时计算的变量,并且仅'valid' 在 API 调用的时间范围内,调用完成后是 'garbage'。

示例:

void A::api()
{
   scratch_pad = get_some_value_once();
   foo1();
}
void A::foo1() { ...; foo2(); }
void A::foo2() { ...; foo3(); }
...
void A::fooN() /* Called 100000000 times */
{ 
     ...; 
     // Do something with scratch_pad.
     // I would realy like to avoid adding 'scratch_pad' parameter to all the foos().
}

这是一种有效的方法吗?

如果我的 API 声明为 const 是否仍然有效?

请不要这样做。

即使您只需要在内部函数调用的生命周期内使用变量,您也会使对象实例更大(占用更多内存)。

您正在使您的函数本质上是多线程不安全的,或者在以前不需要时需要锁定。

您正在使代码本质上变得更少 obvious/maintainable。

如果您想在 API 调用中使用 const,那么您需要开始添加可变变量(呃)。

改用局部变量。检查 Basilevs 的答案以找到一种方法。

一般来说,当成员不是 class 的可观察状态的一部分时,在 const 方法中更改成员的值是可以的。

您必须使用 mutable 关键字标记您的“便签本”会员。
否则,如果您在 const 方法中分配给它,则会出现编译错误。

查看 isocpp 常见问题解答 - https://isocpp.org/wiki/faq/const-correctness#mutable-data-members

class 成员用作临时存储的主要问题是线程安全。当从另一个线程调用方法时,您的内部数据成员存储将以不可预测的方式重用。它还引入了方法之间的隐藏耦合。

实际上,您需要的是一个额外的(可能是不可变的)状态,它具有您的 API 调用的生命周期。在 C++ 中处理状态和生命周期的常用方法是使用 classes.

我建议将新参数提取到新的不可变 class,将所需的方法移动到新的 class 并使 API 实现创建这样的 class 并调用它们.

而不是:

class API {
   private:
   int state;
   void implement() {
     cout << state << endl;
   }
   public:
   void execute() {
      state = 1;
      implement();
   }
}

做:

class State {
   int value;
   public:
   State(int valueArg): value(valueArg) {}
   void implement() const {
     cout << state << endl;
   }

}

class API {
   public:
   void execute() const {
      State(1).implement();
   }
}