今天我已经了解了C ++中的mutable
关键字,并希望在我的代码中使用它。
我有一个包含许多const
方法的类,其中一个应该能够修改一些对象的变量(保留对象的逻辑状态)。但是,我不想让所有const
方法修改变量,只修改选定的变量。有没有办法做到这一点?也许与const_cast
?
(我所讨论的代码是Union-Find structure的实现。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;
};
答案 0 :(得分:3)
乍一看,除非你使用令人讨厌的const_cast,否则无法实现。但是不要这样做,因为尝试修改最初声明为const的const_cast之后的变量的行为是未定义的。
然而,使用友谊来实现你想要的东西可能是可行的,因为这可以在功能的基础上进行控制,而正如你所正确指出的那样,可变性是不可能的。
将要修改的变量放在基类中并将其标记为私有。也许提供一个&#34; getter&#34;对该成员的功能。该函数将是const,并且可能会返回对该成员的const引用。然后让你的函数成为该基类的朋友。该函数将能够更改该私有成员的值。
答案 1 :(得分:-4)
如果你有能力使用% ./Select.sh
0 false
0 true
0 null
0 ""
4 ***ERROR***
,这是正确的方法。
尽管如此,你可以做你想要的事情。通常这是通过“假mutable
”成语:
this
然后通过新指针正常访问您的字段。如果你必须支持一些没有MyClass *mutableThis = const_cast<MyClass*>(this);
支持的旧编译器,这也是这样做的方法。
但请注意,这通常是一种危险的做法,因为它很容易引导您进入未定义行为的可怕领域。如果原始对象实际上是声明 mutable
(而不是仅通过const
指针/引用访问),那么您就会遇到麻烦。
简而言之:尽可能使用const
,当你不能使用假mutable
时,但只有当你知道自己在做什么时才使用this
。