"可变"变量只能由 const 方法之一可变?
'mutable' variable mutable only by one of the const methods?
今天我已经了解了C++中的mutable
关键字,并希望在我的代码中使用它。
我有一个包含许多const
方法的类,其中一个应该能够修改对象的一些变量(保留对象的逻辑状态)。但是,我不想让所有const
方法修改变量,只修改选定的方法。有什么办法可以做到这一点吗?也许有const_cast
?
(我所说的代码是联合查找结构的实现。Find
操作不会更改结构的逻辑状态(它只搜索树的根),而是通过执行所谓的路径压缩来更改物理状态)
谢谢!
编辑:我从我所指的代码中添加了一段摘录:
class UnionFind {
public:
void Union(int a, int b) {...}
int Find(int x) const {
// logically, this method is const
while(x != parents[x]) {
// path compression
// the next three lines modify parents and sizes,
// but the logical state of the object is not changed
sizes[parents[x]] -= sizes[x];
sizes[parents[parents[x]]] += sizes[x];
parents[x] = parents[parents[x]];
x = parents[x];
}
return x;
}
int someOtherMethodThatAccessesParents() const {
// this method does access parents, but read only.
// I would prefer if parents behaved like if it was
// not 'mutable' inside this method
...
}
private:
// these have to be mutable if I want the Find method
// to be marked const (as it should be)
// but making them mutable then does not enforce
// the physical non-mutability in other const methods :(
mutable std::vector<int> parents;
mutable std::vector<int> sizes;
};
乍一看,除非您使用讨厌的const_cast,否则无法实现这一点。但不要这样做,因为在最初声明为 const 的const_cast之后尝试修改变量的行为是未定义的。
但是,使用友谊来实现您想要的东西可能是可行的,因为这可以在逐个功能的基础上进行控制,而可变性,正如您正确指出的那样,不能。
将要修改的变量放在基类中,并将其标记为私有。也许为该成员提供一个"getter"函数。该函数将是 const,并且可能会返回对成员的 const 引用。然后使函数成为该基类的好友。该函数将能够更改该私有成员的值。
如果你能负担得起使用mutable
,这是正确的方法。
尽管如此,还是可以做到你所要求的。通常这是通过"假this
"成语来完成的:
MyClass *mutableThis = const_cast<MyClass*>(this);
然后通过新指针正常访问您的字段。如果您必须支持一些没有mutable
支持的旧编译器,这也是这样做的方法。
但请注意,这通常是一种危险的做法,因为它很容易将您带入未定义行为的可怕领域。如果原始对象实际上被声明为const
(而不是仅通过const
指针/引用进行访问),那么您就是在自找麻烦。
简而言之:尽可能使用mutable
,在不能使用时使用假this
,但前提是你知道自己在做什么。
- 如何在声明为 const 的方法中更改类成员
- 具有参数 (const T *&) 或 (T * &) 或 (const T * const &) 或 (T * const &) 的方法
- 从 const 对象访问非 const 方法
- 为什么我可以调用一个从const方法更改成员的方法
- 使用新的c++返回值语法的Const方法
- MSVC使用constexpr-if从可变模板方法中的基本模板参数中吞下const
- const_cast const 方法中的"this"将"this"分配给外部变量?
- 初始化 const 成员的正确方法
- const 方法使用引用修改对象
- 从类方法返回 "const char*" 作为 std::string&
- 从"wcslen"替换到"strnlen_s"时,用"const char*"进行类型转换是正确的方法吗?
- 将const指针(EVP_MD)保存到变量中,以将其重新使用为类方法(HMAC)
- 为什么 constexpr 假设我的方法就是 const
- 正确的方法通过巨大的const对象的向量
- 使用静态方法初始化 const 类字段的做法是好是坏
- 为什么重写方法并将 const 添加到参数类型有效
- CPP主方法const声明
- 如何基于模板参数制作方法const
- 命名重载的getter方法:const和nonconst
- 声明Get方法const时出错