如何从 const 方法调用非常量方法?
我的类中有一个 const 方法,无法将其更改为非常量。在这个方法中,我需要调用一个非常量方法,但编译器不允许我这样做。
有什么办法解决吗?这是我的代码的简化示例:
int SomeClass::someMethod() const {
QColor saveColor = color();
setColor(QColor(255,255,255)); // Calling non-const method
// ....
setColor(saveColor); // restore color
return 1;
}
I've got a const method in my class, which cannot be changed to non-const. In this method, I need to call a non-const method but the compiler doesn't let me do that.
Is there any way around it? Here is a simplified sample of my code:
int SomeClass::someMethod() const {
QColor saveColor = color();
setColor(QColor(255,255,255)); // Calling non-const method
// ....
setColor(saveColor); // restore color
return 1;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以在
this
指针上使用const_cast
,但如果您对最初声明为
const
的对象执行此操作,则会遇到未定义的行为。所以 this:
没问题,但是 this:
会产生未定义的行为。
真正的解决方案是,您的
const
函数首先就不应该是const
。You could use
const_cast
onthis
pointer,but if you do that for an object that was originally declared
const
you run into undefined behavior.So this:
is okay, but this:
yields undefined behavior.
The real solution is that your
const
function should not beconst
in the first place.实现 const 正确性的挑战之一是不能半途而废。要么全有,要么全无。如果你试图半途而废,你最终会陷入像现在这样的困境。你最终会得到一个很好的
const
正确的类,被一些疯狂的旧的、通常是遗留的(或由老脾气暴躁的人编写的)代码使用,而这些代码不是const
正确的,并且它就是行不通。您会想知道const
的正确性是否值得所有的麻烦。你不能——不能直接调用。你也不应该。但是,还有另一种选择......
显然,您不能从
const
方法调用非const
方法。否则,const 在应用于成员函数时将没有任何意义。const
成员函数可以更改标记为mutable
的成员变量,但您已指出这在您的情况下是不可能的。您可以尝试通过执行诸如
SomeClass* me = const_cast(this);
之类的操作来摆脱 const 性,但是 A) 这通常会导致 UB,或者 2) 它违反了 const 正确性的整个理念。如果您真正想要实现的目标能够支持这一点,您可以做的一件事是创建一个非 const 代理对象,并执行非 const-y 的操作与此。也就是说:
One of the challenges of doing
const
-correctness is you can't do it halfway. It's either all or nothing. If you try to do it halfway, you end up in a tough spot like you are here. You end up with a niceconst
-correct class being used by some crazy old, typically legacy (or written by an old curmudgeon) code that isn'tconst
-correct and it just doesn't work. You're left wondering ifconst
-correctness is worth all the trouble.You can't -- not directly. Nor should you. However, there is an alternative...
Obviously you can't call a non-
const
method from aconst
method. Otherwise,const
would have no meaning when applied to member functions.A
const
member function can change member variables markedmutable
, but you've indicated that this is not possible in your case.You could attempt to cast away
const
ness by doing something likeSomeClass* me = const_cast<SomeClass*>(this);
but A) This will typically result in UB, or 2) It violates the whole idea ofconst
-correctness.One thing you could do, if what you're really trying to accomplish would support this, is to create a non-
const
proxy object, and do nonconst
-y stuff with that. To wit:如果您需要更改
const
方法内的某些内部状态,您还可以声明受影响的状态mutable
:这适用于将互斥体等内容作为以下成员的情况你的班级。获取和释放互斥锁不会影响客户端可见状态,但从技术上讲,在 const 方法中是被禁止的。解决方案是将互斥体标记为
可变
。您的案例看起来很相似,尽管我认为您的课程需要进行一些重构才能适用该解决方案。另外,您可能需要阅读此答案,了解如何使用 RAII 使此临时状态更改异常安全。
If you require to change some internal state inside a
const
-method you can also declare the affected statemutable
:This is intended for cases where you have stuff like mutexes as members of your class. Acquiring and releasing a mutex does not affect client-visible state, but is technically forbidden in a
const
-method. The solution is to mark the mutexmutable
. Your case looks similar, although I think your class requires some refactoring for this solution to be applicable.Also, you might want to read this answer to see how you can make this temporary state-change exception-safe using RAII.
你不应该。如果您使用
const_cast
放弃this
的常量性,则可能会遇到未定义的行为。使用const_cast
会让编译器闭嘴,但这不是解决方案。如果您需要这样做,那么这意味着 const 函数首先不应该是 const 。使其成为非常量。或者,您应该做其他事情,这不需要您从
const
函数调用非常量函数。比如,不调用setColor
函数?比如,将 const 函数拆分为多个函数(如果可以的话)?还是别的什么?在您的特定情况下,如果
setColor
仅设置一些成员变量,例如m_color
,那么您可以将其声明为mutable
:然后将其设置在您的const 函数,不调用
setColor
函数,也不执行const_cast
。You should not. You might run into undefined behaviour if you cast away the const-ness of
this
, usingconst_cast
. The usage ofconst_cast
will shut the compiler's mouth up, but that isn't a solution. If you need to do, then it means the const function should not beconst
in the first place. Make it non-const.Or, you should do something else, which would not require you to call non-const function from
const
function. Like, don't callsetColor
function? Like, split the const function into more than one functions (if you can do that)? Or something else?In your particular case, if
setColor
only sets some member variable, saym_color
, then you can declare itmutable
:and then set it in your const function, without calling
setColor
function, and without doingconst_cast
.