c++ - `const_cast 可以接受吗(this)` 如果公共状态没有改变?
问题描述
我有一个 C++ 类,可以随时随地计算一些统计参数。this
如果我不更改公开可见的状态,并且const
所讨论的函数是幂等且纯/引用透明的,那么抛弃 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
实际上是幂等的,编译器可以计算一次并存储为常量,或内联,或做任何其他事情,因为我的私有状态是可丢弃的。
这是可以接受的事情,还是我要求 UB?
解决方案
const_cast<Foo*>(this)
如果公共状态不改变可以接受吗?
修改 const 对象的非可变状态是未定义的行为。
出于这个原因,除非可以证明所引用的对象是非常量的,否则在 const 转换之后通过对 const 的引用来修改非可变状态是不可接受的。
该状态是否公开无关紧要。我认为这种类型的透明缓存是可变成员存在的原因。
推荐阅读
- python - 有没有办法擦除一列来执行 TSNE?
- react-native - 基于平面列表偏移的 React Native 动画视图位置
- javascript - 使用破坏的打字稿无状态(功能)组件警告?
- vhdl - VHDL 数组索引
- rust - 编译错误 len 作为 const fn 还不稳定
- google-chrome - 在 Firefox/Chrome devtools 有没有办法在连接后发送/编辑 websocket 消息
- javascript - 用文件初始化反应 dropzone
- c# - Linq 连接表并创建动态列错误
- python - 不确定 sklearn 中的 PCA
- json - 如何使用ajax将数组或数组列表从servlet传递到jsp?