如何从const方法调用非const方法
How to call a non-const method from a const method?
我的类中有一个const方法,它不能更改为非const。在这个方法中,我需要调用一个非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
-正确性的挑战之一是你不能半途而废。要么全有,要么全无。如果你半途而废,你就会像现在这样陷入困境。你最终会得到一个很好的const
正确的类被一些疯狂的旧的,通常是遗留的(或由一个老脾气写的)代码所使用,这些代码不是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
,但是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
-方法中的一些内部状态,您也可以声明受影响的状态mutable
:
class Foo {
public:
void doStuff() const { bar = 5; }
private:
mutable int bar;
};
这适用于有互斥体之类的东西作为类成员的情况。获取和释放互斥锁不会影响客户端可见状态,但在const
方法中技术上是禁止的。解决方案是将互斥标记为mutable
。您的情况看起来类似,尽管我认为您的类需要一些重构才能适用此解决方案。
另外,您可能希望阅读此回答,了解如何使用RAII使此临时状态更改异常安全。
如何从const方法调用非const方法?
你不应该。如果使用const_cast
抛弃this
的const-ness,可能会遇到未定义的行为。使用const_cast
会堵住编译器的嘴,但这不是解决方案。如果您需要这样做,那么这意味着const函数首先不应该是const
。设置为非const
或者,您应该做其他事情,这将不需要您从const
函数调用非const函数。比如,不要调用setColor
函数?比如,将const函数拆分为多个函数(如果可以的话)?还是别的什么?
在您的特殊情况下,如果setColor
只设置了某个成员变量,例如m_color
,那么您可以将其声明为mutable
:
mutable QColor m_color;
,然后在const函数中设置它,不调用setColor
函数,也不执行const_cast
。
- 如何在声明为 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时出错