D 有两种 const 类型:不可变变量是被声明为不可变的变量,并且始终是不可变的,而const变量只是对象的只读版本。
逻辑 const是指函数被标记为const,但允许对一个或多个成员变量进行写访问。它的典型用途是惰性求值,例如(在 C++ 中)
struct Matrix
{
double determinant() const
{
if ( m_dirty )
{
m_determinant = /* expensive calculation */;
m_dirty = false;
}
return m_determinant;
}
void set(int i, int j, double x) { m_dirty = true; ...; }
mutable bool m_dirty;
mutable double m_determinant;
};
在这里,determinant()
是const
,但仍然可以修改m_dirty
,并且m_determinant
由于它们被标记为mutable
。
D const(FAQ)说 D2 不支持逻辑 const,因为它提供的保证很弱,这阻碍了编写并发程序,并使某些优化更加困难。
我完全理解这个问题,但是如果我们需要逻辑常量怎么办?
考虑上面带有Matrix
类的情况,但没有缓存(并且不需要任何逻辑常量)。还可以想象这个类在我的代码库中使用,并且主要通过 const 引用访问。
现在考虑分析表明该determinant()
函数是代码中的瓶颈,此外,它通常被重复访问,其值很少改变,即缓存,如上所述,将是一个完美的优化。
如果没有逻辑常量,我怎么能做到这一点?遍历我的代码库将 const 引用更改为非 const 引用不是一种选择(出于显而易见的原因)。
我有哪些选择(如果有)?