有一个修改 '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();
}
}
我会描述问题。我有一个带有 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();
}
}