[英]How to call a non-const method from a const method?
我的类中有一个 const 方法,它不能更改为非常量。 在这种方法中,我需要调用一个非常量方法,但编译器不允许我这样做。
有什么办法可以解决吗? 这是我的代码的简化示例:
int SomeClass::someMethod() const {
QColor saveColor = color();
setColor(QColor(255,255,255)); // Calling non-const method
// ....
setColor(saveColor); // restore color
return 1;
}
你可以在this
指针上使用const_cast
,
int SomeClass::someMethod() const {
const_cast<SomeClass*>( this )->setColor(...);// Calling non-const method
//whatever
}
但是如果你对一个最初声明为const
的对象这样做,你会遇到未定义的行为。
所以这:
SomeClass object;
object.someMethod();
没关系,但是这个:
const SomeClass object;
object.someMethod();
产生未定义的行为。
真正的解决方案是您的const
函数首先不应该是const
。
如果您需要更改const
方法内的某些内部状态,您还可以声明受影响的状态mutable
:
class Foo {
public:
void doStuff() const { bar = 5; }
private:
mutable int bar;
};
这适用于您将互斥锁之类的东西作为类成员的情况。 获取和释放互斥锁不会影响客户端可见的状态,但在const
方法中在技术上是禁止的。 解决方案是将互斥锁标记为mutable
。 您的情况看起来很相似,但我认为您的课程需要进行一些重构才能使此解决方案适用。
此外,您可能想阅读此答案以了解如何使用 RAII 使此临时状态更改异常安全。
做const
正确性的挑战之一是你不能半途而废。 要么全有,要么全无。 如果你尝试半途而废,你最终会陷入困境,就像你在这里一样。 你最终会得到一个不错的const
-correct 类,它被一些疯狂的旧的、典型的遗留(或由一个旧的脾气暴躁的人编写)代码使用,这些代码不是const
正确的,它只是不起作用。 你会想知道const
正确性是否值得所有的麻烦。
I need to call a non-const method [from a const method]
你不能——不能直接。 你也不应该。 但是,还有一种替代方法......
显然,你不能调用非const
从方法const
方法。 否则,当应用于成员函数时, const
将毫无意义。
const
成员函数可以更改标记为mutable
成员变量,但您已经指出这在您的情况下是不可能的。
您可以尝试通过执行SomeClass* me = const_cast<SomeClass*>(this);
类的操作来摆脱const
性SomeClass* me = const_cast<SomeClass*>(this);
但是 A) 这通常会导致 UB,或 2) 它违反了const
正确性的整个想法。
如果您真正想要完成的事情支持这一点,您可以做的一件事是创建一个非const
代理对象,并使用它执行非const
-y 的事情。 以机智:
#include <iostream>
#include <string>
using namespace std;
class Gizmo
{
public:
Gizmo() : n_(42) {};
void Foo() const;
void Bar() { cout << "Bar() : " << n_ << "\n"; }
void SetN(int n) { n_ = n; };
int GetN() const { return n_; }
private:
int n_;
};
void Gizmo::Foo() const
{
// we want to do non-const'y things, so create a proxy...
Gizmo proxy(*this);
int save_n = proxy.GetN();
proxy.SetN(save_n + 1);
proxy.Bar();
proxy.SetN(save_n);
}
int main()
{
Gizmo gizmo;
gizmo.Foo();
}
如何从 const 方法调用非常量方法?
你不应该。 如果您使用const_cast
抛弃this
的常量性,您可能会遇到未定义的行为。 const_cast
的使用会使编译器闭嘴,但这不是解决方案。 如果你需要这样做,那么这意味着 const 函数首先不应该是const
。 使它成为非常量。
或者,您应该做一些其他事情,这不需要您从const
函数调用非常量函数。 比如,不要调用setColor
函数? 比如,将 const 函数拆分为多个函数(如果可以的话)? 或者是其他东西?
在您的特定情况下,如果setColor
仅设置一些成员变量,例如m_color
,那么您可以将其声明为mutable
:
mutable QColor m_color;
然后在您的 const 函数中设置它,而不调用setColor
函数,也不执行const_cast
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.