【发布时间】:2017-04-18 20:09:24
【问题描述】:
假设我们有一个类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;
}
当然上面的代码不能编译。以下是我知道的两种解决方法:
const_cast<A*>(this)->bmutable B b;
这些解决方案都不是完美的。解决方案1涉及UB当A的实例本身为const时;并且解决方案 2 将可变性暴露给整个类,因此它不能防止编码人员意外修改其他 const 成员函数中的 b。
const_cast 是“本地”,但可能会触发 UB; mutable 是内存安全的,但也太“全局”了。
那么有没有第三种解决方案,还是我理解错了?
【问题讨论】:
-
你不能代替
tiny_change(b)开发tiny_change(result)并在未更改的B上计算结果。 -
你不能重载
compute来获取“小零钱”并使用它来代替b的任何值吗?B显然与您的类的逻辑常量有关,而不仅仅是按位。在这种情况下,这两种解决方案都是 hack。 -
@Zereges 这些函数在我的例子中不是同态的
-
@StoryTeller 在我的情况下,
B是一个大数组,任何数组元素都可能发生“小变化”。compute(b)是基于 CPU 敏感的递归,所以直接修改b可能是最便宜的。 -
在多线程上下文中小心这种方法。 const 成员函数通常是线程安全的。如果您要更改
b,则情况并非如此,您需要一个互斥锁来保证线程安全。
标签: c++ mutable const-cast