我有一个C++类,可以在运行中计算一些统计参数。是否可以接受将const从 this
来实现冗长计算的缓存,如果我不改变公开可见的状态,而 const
的函数是幂等的,而且是纯粹透明的?
#include <cstdio>
#include <unistd.h>
class Compute {
public:
Compute() = default;
~Compute() = default;
void add(int x) {
sum += x;
squareDirty = true;
}
int getSquare() const {
if (squareDirty) {
auto &mthis = *const_cast<Compute*>(this);
usleep(2000); // takes a long time!
mthis.squareCached = sum * sum;
mthis.squareDirty = false;
}
return squareCached;
}
private:
int sum = 0;
bool squareDirty = false;
int squareCached;
};
void foo() {
Compute c{};
c.add(10);
c.add(20);
printf("%d\n", c.getSquare()); // long time...
printf("%d\n", c.getSquare()); // fast!
}
我想只在真正需要的时候才懒得计算东西--并缓存它们直到新的数据到来。
然而,我希望在实际需要的时候才懒得计算这些东西--并将它们缓存起来,直到新的数据到来。缓存 事情的意思是,我 T getSquare() const
方法将不得不抛开 const
从 this
来突变私人国家。
但由于 getSquare
是有效的idempotent,编译器可以计算一次,然后存储为常量,或者内联,或者做其他任何事情,因为我的私有状态是可以丢弃的。
这是一个可以接受的事情,还是我自找的UB?
这个问题可以通过使用 mutable
关键字。这个关键字表示成员变量可以在 const
的限定函数。
struct S
{
mutable int x; // some data that is not relevant to users of the object (e.g. a cache variable)
int y;
void f() const
{
x = 42; // fine
y = 42; // error
}
};
这是在const限定函数中修改变量的更好的方法, 比起放弃const-correctness, 或者用 const_cast
(这是UB的一个潜在来源)。
请注意,当你做一个函数 const
你实际上保证了比 "可见状态不被改变 "更多的东西。你保证通过任何 const 函数对对象的访问是线程安全的。这意味着,如果你有 mutable
变量,如果多个线程可能同时访问它们,你应该仔细考虑它们的状态。在这种情况下,你可能应该考虑自己手动同步对这个变量的访问。
是否可以接受
const_cast<Foo*>(this)
如果公共状态没有改变?
修改const对象的非可变状态是未定义的行为。
出于这个原因,在const cast之后通过引用const来修改非可变状态是不可接受的,除非可以证明引用的对象是非const的。
该状态是否为公共状态是不相关的。我想,这种类型的透明缓存是可变成员存在的原因。
使用
auto &mthis = *const_cast<Compute*>(this);
mthis.squareCached = sum * sum;
mthis.squareDirty = false;
可以导致未定义的行为。这取决于原始对象是如何构造的。
从 https:/en.cppreference.comwcpplanguageconst_cast。:
修改a
const
对象通过非const
访问路径,并指向volatile
对象通过非volatile
glvalue导致未定义的行为。
最好是将相关成员 mutable
.
int sum = 0;
mutable bool squareDirty = false;
mutable int squareCached;
然后,你可以使用。
int getSquare() const {
if (squareDirty) {
usleep(2000); // takes a long time!
this->squareCached = sum * sum;
this->squareDirty = false;
}
return squareCached;
}
而不必担心未定义的行为。